From fb123f93f9f5ce42c8e5785d2f8e0edaf951740e Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Wed, 26 Mar 2014 19:21:20 +0000 Subject: Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2. --- src/VBox/Main/testcase/Makefile.kmk | 110 ++-- src/VBox/Main/testcase/VBoxVBTest/VBoxVBTest.vbp | 2 +- src/VBox/Main/testcase/makefile.tstVBoxAPILinux | 48 -- src/VBox/Main/testcase/makefile.tstVBoxAPIWin | 88 +++ src/VBox/Main/testcase/makefile.tstVBoxAPIXPCOM | 48 ++ src/VBox/Main/testcase/tstAPI.cpp | 41 +- src/VBox/Main/testcase/tstCollector.cpp | 539 +++++++++-------- src/VBox/Main/testcase/tstGuestCtrlContextID.cpp | 27 +- src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp | 2 +- src/VBox/Main/testcase/tstMediumLock.cpp | 299 ++++++++++ src/VBox/Main/testcase/tstMouseImpl.cpp | 459 +++++++++++++++ src/VBox/Main/testcase/tstOVF.cpp | 15 +- src/VBox/Main/testcase/tstUSBLinux.h | 2 +- src/VBox/Main/testcase/tstVBoxAPILinux.cpp | 629 -------------------- src/VBox/Main/testcase/tstVBoxAPIWin.cpp | 2 +- src/VBox/Main/testcase/tstVBoxAPIXPCOM.cpp | 655 +++++++++++++++++++++ 16 files changed, 1974 insertions(+), 992 deletions(-) delete mode 100644 src/VBox/Main/testcase/makefile.tstVBoxAPILinux create mode 100644 src/VBox/Main/testcase/makefile.tstVBoxAPIWin create mode 100644 src/VBox/Main/testcase/makefile.tstVBoxAPIXPCOM create mode 100644 src/VBox/Main/testcase/tstMediumLock.cpp create mode 100644 src/VBox/Main/testcase/tstMouseImpl.cpp delete mode 100644 src/VBox/Main/testcase/tstVBoxAPILinux.cpp create mode 100644 src/VBox/Main/testcase/tstVBoxAPIXPCOM.cpp (limited to 'src/VBox/Main/testcase') diff --git a/src/VBox/Main/testcase/Makefile.kmk b/src/VBox/Main/testcase/Makefile.kmk index 76ba6455..e08f5979 100644 --- a/src/VBox/Main/testcase/Makefile.kmk +++ b/src/VBox/Main/testcase/Makefile.kmk @@ -4,7 +4,7 @@ # # -# Copyright (C) 2004-2012 Oracle Corporation +# Copyright (C) 2004-2013 Oracle Corporation # # This file is part of VirtualBox Open Source Edition (OSE), as # available from http://www.virtualbox.org. This file is free software; @@ -18,6 +18,7 @@ SUB_DEPTH = ../../../.. include $(KBUILD_PATH)/subheader.kmk + # # Target and globals (small mess) # @@ -26,10 +27,12 @@ ifndef VBOX_ONLY_SDK PROGRAMS += \ tstAPI \ $(if $(VBOX_OSE),,tstOVF) \ - $(if $(VBOX_WITH_XPCOM),tstVBoxAPILinux,tstVBoxAPIWin) \ + $(if $(VBOX_WITH_XPCOM),tstVBoxAPIXPCOM,tstVBoxAPIWin) \ $(if $(VBOX_WITH_RESOURCE_USAGE_API),tstCollector,) \ $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlParseBuffer,) \ - $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlContextID,) + $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlContextID,) \ + tstMediumLock \ + tstMouseImpl PROGRAMS.linux += \ $(if $(VBOX_WITH_USB),tstUSBProxyLinux,) endif # !VBOX_WITH_TESTCASES @@ -47,43 +50,27 @@ endif # samplesMSCOM_MODE = a+r,u+w samplesMSCOM_INST = $(INST_SDK)bindings/mscom/samples/ -samplesMSCOM_SOURCES = tstVBoxAPIWin.cpp +samplesMSCOM_SOURCES = tstVBoxAPIWin.cpp makefile.tstVBoxAPIWin=>Makefile samplesXPCOM_MODE = a+r,u+w samplesXPCOM_INST = $(INST_SDK)bindings/xpcom/samples/ -samplesXPCOM_SOURCES = tstVBoxAPILinux.cpp makefile.tstVBoxAPILinux=>Makefile +samplesXPCOM_SOURCES = tstVBoxAPIXPCOM.cpp makefile.tstVBoxAPIXPCOM=>Makefile # # tstAPI # -tstAPI_TEMPLATE = VBOXMAINCLIENTEXE +tstAPI_TEMPLATE = VBOXMAINCLIENTTSTEXE #tstAPI_INST = $(INST_SDK)bindings/gluecom/samples/ tstAPI_SOURCES = tstAPI.cpp -ifeq ($(KBUILD_TARGET),win) ## @todo just add this to the template. -tstAPI_DEPS = $(VBOX_PATH_SDK)/bindings/mscom/include/VirtualBox.h -else -tstAPI_DEPS = $(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h -endif -ifdef VBOX_WITH_RESOURCE_USAGE_API -tstAPI_DEFS += VBOX_WITH_RESOURCE_USAGE_API -endif # # tstOVF # -tstOVF_TEMPLATE = VBOXMAINCLIENTEXE +tstOVF_TEMPLATE = VBOXMAINCLIENTTSTEXE #tstOVF_INST = $(INST_SDK)bindings/gluecom/samples/ tstOVF_SOURCES = tstOVF.cpp -ifeq ($(KBUILD_TARGET),win) ## @todo just add this to the template. -tstOVF_DEPS = $(VBOX_PATH_SDK)/bindings/mscom/include/VirtualBox.h -else -tstOVF_DEPS = $(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h -endif -ifdef VBOX_WITH_RESOURCE_USAGE_API -tstOVF_DEFS += VBOX_WITH_RESOURCE_USAGE_API -endif ifndef VBOX_OSE # @@ -101,82 +88,58 @@ endif # -# tstVBoxAPILinux +# tstVBoxAPIXPCOM # # We only build the testcase here to make sure it builds. # It comes with a custom makefile which should be tested as well! # -tstVBoxAPILinux_TEMPLATE = VBOXR3EXE -tstVBoxAPILinux_SOURCES = tstVBoxAPILinux.cpp -tstVBoxAPILinux_CXXFLAGS = -Wno-non-virtual-dtor -fshort-wchar -tstVBoxAPILinux_LDFLAGS.solaris += '$(VBOX_GCC_RPATH_OPT)$$(VBOX_ORIGIN)/../../..' -ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP - tstVBoxAPILinux_DEFS += VBOX_WITH_XPCOM_NAMESPACE_CLEANUP -endif -tstVBoxAPILinux_INCS = \ - $(VBOX_XPCOM_INCS) \ - $(VBOX_PATH_SDK)/bindings/xpcom/include -tstVBoxAPILinux_LIBPATH = $(LIBPATH_XPCOM) -tstVBoxAPILinux_LIBS = $(LIB_XPCOM) $(LIB_RUNTIME) -tstVBoxAPILinux_DEPS = \ - $(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h +tstVBoxAPIXPCOM_TEMPLATE = VBOXMAINCLIENTTSTEXE +tstVBoxAPIXPCOM_SOURCES = tstVBoxAPIXPCOM.cpp # # tstVBoxAPIWin # -tstVBoxAPIWin_TEMPLATE = VBOXMAINCLIENTEXE +tstVBoxAPIWin_TEMPLATE = VBOXMAINCLIENTTSTEXE tstVBoxAPIWin_SOURCES = \ tstVBoxAPIWin.cpp \ $(VBOX_PATH_SDK)/bindings/mscom/lib/VirtualBox_i.c -tstVBoxAPIWin_DEPS = \ - $(VBOX_PATH_SDK)/bindings/mscom/include/VirtualBox.h # # tstCollector # -tstCollector_TEMPLATE = VBOXMAINCLIENTEXE +tstCollector_TEMPLATE = VBOXMAINCLIENTTSTEXE tstCollector_SOURCES = \ tstCollector.cpp \ ../src-server/Performance.cpp tstCollector_INCS = ../include tstCollector_DEFS += VBOX_COLLECTOR_TEST_CASE tstCollector_LDFLAGS.darwin += -lproc -tstCollector_LDFLAGS.solaris += -lkstat +tstCollector_LDFLAGS.solaris += -lkstat -lnvpair tstCollector_LDFLAGS.win += psapi.lib powrprof.lib # # tstGuestCtrlParseBuffer # -tstGuestCtrlParseBuffer_TEMPLATE = VBOXMAINCLIENTEXE -tstGuestCtrlParseBuffer_DEFS += VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL +tstGuestCtrlParseBuffer_TEMPLATE = VBOXMAINCLIENTTSTEXE +tstGuestCtrlParseBuffer_DEFS += VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL VBOX_GUESTCTRL_TEST_CASE tstGuestCtrlParseBuffer_SOURCES = \ tstGuestCtrlParseBuffer.cpp \ ../src-client/GuestCtrlPrivate.cpp tstGuestCtrlParseBuffer_INCS = ../include -ifeq ($(KBUILD_TARGET),win) ## @todo just add this to the template. - tstGuestCtrlParseBuffer_DEPS = $(VBOX_PATH_SDK)/bindings/mscom/include/VirtualBox.h -else - tstGuestCtrlParseBuffer_DEPS = $(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h -endif # # tstGuestCtrlContextID # -tstGuestCtrlContextID_TEMPLATE = VBOXMAINCLIENTEXE -tstGuestCtrlContextID_DEFS += VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL +tstGuestCtrlContextID_TEMPLATE = VBOXMAINCLIENTTSTEXE +tstGuestCtrlContextID_DEFS += VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL VBOX_GUESTCTRL_TEST_CASE tstGuestCtrlContextID_SOURCES = \ tstGuestCtrlContextID.cpp \ ../src-client/GuestCtrlPrivate.cpp tstGuestCtrlContextID_INCS = ../include -ifeq ($(KBUILD_TARGET),win) ## @todo just add this to the template. - tstGuestCtrlContextID_DEPS = $(VBOX_PATH_SDK)/bindings/mscom/include/VirtualBox.h -else - tstGuestCtrlContextID_DEPS = $(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h -endif # @@ -205,6 +168,39 @@ tstUSBProxyLinux_LIBS += \ $(PATH_OUT)/lib/VBoxCOM.a +# +# tstMediumLock +# +tstMediumLock_TEMPLATE = VBOXMAINCLIENTTSTEXE +tstMediumLock_SOURCES = tstMediumLock.cpp + + +# +# tstMouseImpl +# +tstMouseImpl_TEMPLATE = VBOXMAINTSTEXE +tstMouseImpl_SOURCES = \ + tstMouseImpl.cpp \ + ../src-client/MouseImpl.cpp \ + ../src-all/EventImpl.cpp \ + ../src-all/VirtualBoxBase.cpp \ + ../src-all/VirtualBoxErrorInfoImpl.cpp \ + $(VBOX_AUTOGEN_EVENT_CPP) \ + $(VBOX_XML_SCHEMADEFS_CPP) +tstMouseImpl_INCS = ../include \ + $(VBOX_PATH_SDK)/bindings/xpcom/include \ + $(VBOX_PATH_SDK)/bindings/xpcom/include/nsprpub \ + $(VBOX_PATH_SDK)/bindings/xpcom/include/xpcom \ + $(dir $(VBOX_XML_SCHEMADEFS_H)) +tstMouseImpl_LIBS = \ + $(PATH_STAGE_LIB)/VBoxAPIWrap$(VBOX_SUFF_LIB) \ + $(LIB_VMM) +# Super ugly hack to make the code work well enough without having ATL/COM +# completely initialized, without it there are crashes caused by ComObjPtr +# and many other pieces of glue code, as the inproc code path is more picky. +tstMouseImpl_DEFS.win += VBOX_COM_OUTOFPROC_MODULE + + # generate rules. include $(FILE_KBUILD_SUB_FOOTER) diff --git a/src/VBox/Main/testcase/VBoxVBTest/VBoxVBTest.vbp b/src/VBox/Main/testcase/VBoxVBTest/VBoxVBTest.vbp index a2e6c1bc..cdc19c8a 100644 --- a/src/VBox/Main/testcase/VBoxVBTest/VBoxVBTest.vbp +++ b/src/VBox/Main/testcase/VBoxVBTest/VBoxVBTest.vbp @@ -1,6 +1,6 @@ Type=Exe Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\WINDOWS\system32\stdole2.tlb#OLE Automation -Reference=*\G{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}#1.0#0#VBoxC.dll#InnoTek VirtualBox Machine Type Library +Reference=*\G{D7569351-1750-46F0-936E-BD127D5BC264}#1.3#0#VBoxC.dll#InnoTek VirtualBox Machine Type Library Form=TestForm.frm Startup="TestForm" ExeName32="VBoxVBTest.exe" diff --git a/src/VBox/Main/testcase/makefile.tstVBoxAPILinux b/src/VBox/Main/testcase/makefile.tstVBoxAPILinux deleted file mode 100644 index 4239d50e..00000000 --- a/src/VBox/Main/testcase/makefile.tstVBoxAPILinux +++ /dev/null @@ -1,48 +0,0 @@ -# -# tstVBoxAPILinux 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. -# - -PATH_XPCOM = .. -PATH_BIN = ../../../../ - -# This setting must be the same as used when building VBoxXPCOM.so. -# If you get a lot of unresolved symbols, try commenting it out. -VBOX_WITH_XPCOM_NAMESPACE_CLEANUP=1 - -PATH_XPCOM_IDL = $(PATH_XPCOM)/idl -INCS_XPCOM = $(PATH_XPCOM)/include \ - $(PATH_XPCOM)/include/nsprpub \ - $(PATH_XPCOM)/include/string \ - $(PATH_XPCOM)/include/xpcom \ - $(PATH_XPCOM)/include/ipcd - -ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP - DEFS_XPCOM += VBOX_WITH_XPCOM_NAMESPACE_CLEANUP -endif - - -# -# Link with the public XPCOM libraries -# -tstVBoxAPILinux: tstVBoxAPILinux.o - g++ -g -o $@ $^ \ - $(PATH_BIN)/VBoxXPCOM.so \ - -Wl,-rpath $(PATH_BIN)/ \ - -ldl -lpthread - -tstVBoxAPILinux.o: tstVBoxAPILinux.cpp - g++ -c -DRT_OS_LINUX -g -fshort-wchar $(addprefix -I, $(INCS_XPCOM)) $(addprefix -D, $(DEFS_XPCOM)) -o $@ tstVBoxAPILinux.cpp - -clean: - rm -f tstVBoxAPILinux tstVBoxAPILinux.o diff --git a/src/VBox/Main/testcase/makefile.tstVBoxAPIWin b/src/VBox/Main/testcase/makefile.tstVBoxAPIWin new file mode 100644 index 00000000..fbbc16bf --- /dev/null +++ b/src/VBox/Main/testcase/makefile.tstVBoxAPIWin @@ -0,0 +1,88 @@ +# +# tstVBoxAPILinux makefile +# +# +# Copyright (C) 2006-2013 Oracle Corporation +# +# This file is part of VirtualBox Open Source Edition (OSE), as +# available from http://www.virtualbox.org. This file is free software; +# you can redistribute it and/or modify it under the terms of the GNU +# General Public License (GPL) as published by the Free Software +# Foundation, in version 2 as it comes in the "COPYING" file of the +# VirtualBox OSE distribution. VirtualBox OSE is distributed in the +# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +# +# Several assumptions and propositions: +# - Visual Studio has already installed on machine or you already have nmake.exe, cl.exe, link.exe +# - Windows SDK has already installed on machine or you already have Uuid.Lib Ole32.Lib OleAut32.Lib OleDlg.Lib +# - VirtualBox SDK was downloaded and was placed into folder where VirtualBox had been installed. +# - nmake is a default tool that builds projects based on commands contained in this description file +# - cl is cl.exe - Windows compiler +# - link is link.exe - Windows linker +# - all needed paths have been set in working environment. It means that when you type "cl" from the console, +# Windows shall find cl.exe by using enviroment variable PATH or something similar. +# +# The best way to accomplish it is to run a script vcvars32.bat located in the Visual studio "bin" directory. +# This script installs needed paths in your working environment. +# Important!!! +# Script vcvars32.bat sets up needed paths only for local console session. +# For permanent using, needed paths must be added globally. +# +# Several possible examples of paths: +# VS_INSTALL_PATH = "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\" +# VS_INCLUDE_PATH = "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include" +# VS_ATLMFC_INCLUDE_PATH = "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include" +# WIN_SDK_INCLUDE_PATH = "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include" +# WIN_SDK_LIB_PATH = "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib\x64\" +# VB_INSTALL_PATH = "C:\Program Files\Oracle\VirtualBox" +# + + +CXX = cl +LINK = link +PATH_MSCOM = ../../../bindings/mscom +INCS_MSCOM = $(PATH_MSCOM)/include +LIBS_MSCOM = $(PATH_MSCOM)/lib + +LIBS_DEPS = "Uuid.Lib" "Ole32.Lib" "OleAut32.Lib" "OleDlg.Lib" + +tstVBoxAPIWin_SOURCES = $(LIBS_MSCOM)/VirtualBox_i.c +tstVBoxAPIWin_DEPS = $(INCS_MSCOM) + +COMPILER_CMDLINE = /Zi /nologo /W3 /WX- /Od /Oy- /Gm /EHsc /RTC1 /GS /fp:precise /Gd /analyze- /errorReport:queue + +LINKER_CMDLINE = /INCREMENTAL /DEBUG /SUBSYSTEM:CONSOLE + +# default linking +tstVBoxAPIWin.exe: tstVBoxAPIWin.obj VirtualBox_i.obj + $(LINK) /out:tstVBoxAPIWin.exe $** $(LIBS_DEPS) + +# default compilation +tstVBoxAPIWin.obj: + $(CXX) /c /I$(INCS_MSCOM) tstVBoxAPIWin.cpp + +# default compilation +VirtualBox_i.obj: + $(CXX) /c /I$(INCS_MSCOM) $(tstVBoxAPIWin_SOURCES) + +# linking with defined linker's options +#tstVBoxAPIWin.exe: tstVBoxAPIWin.obj VirtualBox_i.obj +# $(LINK) $(LINKER_CMDLINE) /out:tstVBoxAPIWin.exe $** $(LIBS_DEPS) + +# compile with pre-defined compiler's options and locally defined paths +#tstVBoxAPIWin.obj: +# $(CXX) /c $(COMPILER_CMDLINE) /I$(INCS_MSCOM) /I$(WIN_SDK_INCLUDE_PATH) /I$(VS_INCLUDE_PATH) tstVBoxAPIWin.cpp + +# compile with locally defined paths +#tstVBoxAPIWin.obj: +# $(CXX) /c /I$(INCS_MSCOM) /I$(WIN_SDK_INCLUDE_PATH) /I$(VS_INCLUDE_PATH) tstVBoxAPIWin.cpp + +# compile with pre-defined compiler's options and locally defined paths +#VirtualBox_i.obj: +# $(CXX) /c $(COMPILER_CMDLINE) /I$(INCS_MSCOM) /I$(WIN_SDK_INCLUDE_PATH) /I$(VS_INCLUDE_PATH) $(tstVBoxAPIWin_SOURCES) + +# compile with locally defined paths +#VirtualBox_i.obj: +# $(CXX) /c /I$(INCS_MSCOM) /I$(WIN_SDK_INCLUDE_PATH) /I$(VS_INCLUDE_PATH) $(tstVBoxAPIWin_SOURCES) + + diff --git a/src/VBox/Main/testcase/makefile.tstVBoxAPIXPCOM b/src/VBox/Main/testcase/makefile.tstVBoxAPIXPCOM new file mode 100644 index 00000000..09fc2b80 --- /dev/null +++ b/src/VBox/Main/testcase/makefile.tstVBoxAPIXPCOM @@ -0,0 +1,48 @@ +# +# tstVBoxAPIXPCOM makefile +# +# +# Copyright (C) 2006-2013 Oracle Corporation +# +# This file is part of VirtualBox Open Source Edition (OSE), as +# available from http://www.virtualbox.org. This file is free software; +# you can redistribute it and/or modify it under the terms of the GNU +# General Public License (GPL) as published by the Free Software +# Foundation, in version 2 as it comes in the "COPYING" file of the +# VirtualBox OSE distribution. VirtualBox OSE is distributed in the +# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +# + +PATH_XPCOM = .. +PATH_BIN = ../../../../ + +# This setting must be the same as used when building VBoxXPCOM.so. +# If you get a lot of unresolved symbols, try commenting it out. +VBOX_WITH_XPCOM_NAMESPACE_CLEANUP=1 + +PATH_XPCOM_IDL = $(PATH_XPCOM)/idl +INCS_XPCOM = $(PATH_XPCOM)/include \ + $(PATH_XPCOM)/include/nsprpub \ + $(PATH_XPCOM)/include/string \ + $(PATH_XPCOM)/include/xpcom \ + $(PATH_XPCOM)/include/ipcd + +ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP + DEFS_XPCOM += VBOX_WITH_XPCOM_NAMESPACE_CLEANUP +endif + + +# +# Link with the public XPCOM libraries +# +tstVBoxAPIXPCOM: tstVBoxAPIXPCOM.o + g++ -g -o $@ $^ \ + $(PATH_BIN)/VBoxXPCOM.so \ + -Wl,-rpath $(PATH_BIN)/ \ + -ldl -lpthread + +tstVBoxAPIXPCOM.o: tstVBoxAPIXPCOM.cpp + g++ -c -g -fshort-wchar $(addprefix -I, $(INCS_XPCOM)) $(addprefix -D, $(DEFS_XPCOM)) -o $@ tstVBoxAPIXPCOM.cpp + +clean: + rm -f tstVBoxAPIXPCOM tstVBoxAPIXPCOM.o diff --git a/src/VBox/Main/testcase/tstAPI.cpp b/src/VBox/Main/testcase/tstAPI.cpp index 978d0a25..a18499e4 100644 --- a/src/VBox/Main/testcase/tstAPI.cpp +++ b/src/VBox/Main/testcase/tstAPI.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 Oracle Corporation + * Copyright (C) 2006-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -24,7 +24,6 @@ #include #include #include -#include #include @@ -369,11 +368,6 @@ int main(int argc, char *argv[]) } #endif - // create the event queue - // (here it is necessary only to process remaining XPCOM/IPC events - // after the session is closed) - EventQueue eventQ; - #if 0 // the simplest COM API test //////////////////////////////////////////////////////////////////////////// @@ -1157,7 +1151,7 @@ int main(int argc, char *argv[]) RTPrintf("\n"); #endif -#if 0 +#if 1 do { // Get host ComPtr host; @@ -1212,6 +1206,35 @@ int main(int argc, char *argv[]) } while (0); #endif +#if 0 + // DNS & Co. + /////////////////////////////////////////////////////////////////////////// + /* XXX: Note it's endless loop */ + do + { + ComPtr host; + CHECK_ERROR_BREAK(virtualBox, COMGETTER(Host)(host.asOutParam())); + + { + Bstr domainName; + CHECK_ERROR_BREAK(host,COMGETTER(DomainName)(domainName.asOutParam())); + RTPrintf("Domain name: %ls\n", domainName.raw()); + } + + com::SafeArray strs; + CHECK_ERROR_BREAK(host, COMGETTER(NameServers)(ComSafeArrayAsOutParam(strs))); + + unsigned int i; + for (i = 0; i < strs.size(); ++i) + RTPrintf("Name server[%d]:%s\n", i, com::Utf8Str(strs[i]).c_str()); + + RTThreadSleep(1000); + } + while (1); + RTPrintf("\n"); +#endif + + #if 0 && defined(VBOX_WITH_RESOURCE_USAGE_API) do { // Get collector @@ -1495,7 +1518,7 @@ int main(int argc, char *argv[]) /* get the mutable session machine */ session->COMGETTER(Machine)(machine.asOutParam()); CHECK_ERROR_BREAK(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam())); - + RTPrintf("Creating bandwidth group named '%ls'...\n", grpName.raw()); CHECK_ERROR_BREAK(bwCtrl, CreateBandwidthGroup(grpName.raw(), BandwidthGroupType_Network, 123)); diff --git a/src/VBox/Main/testcase/tstCollector.cpp b/src/VBox/Main/testcase/tstCollector.cpp index 1798d30e..63aaff4f 100644 --- a/src/VBox/Main/testcase/tstCollector.cpp +++ b/src/VBox/Main/testcase/tstCollector.cpp @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -63,7 +63,7 @@ if (RT_FAILURE(rc)) \ break; \ ++nCalls; \ - } while(RTTimeMilliTS() - start < RUN_TIME_MS); \ + } while (RTTimeMilliTS() - start < RUN_TIME_MS); \ if (RT_FAILURE(rc)) \ { \ RTPrintf("tstCollector: "#fn" -> %Rrc\n", rc); \ @@ -152,8 +152,9 @@ int testNetwork(pm::CollectorHAL *collector) uint64_t hostRxStart, hostTxStart; uint64_t hostRxStop, hostTxStop, speed = 125000000; /* Assume 1Gbit/s */ - RTPrintf("tstCollector: TESTING - Network load, sleeping for 5 sec...\n"); + RTPrintf("tstCollector: TESTING - Network load, sleeping for 5 s...\n"); + hostRxStart = hostTxStart = 0; int rc = collector->preCollect(hints, 0); if (RT_FAILURE(rc)) { @@ -161,36 +162,43 @@ int testNetwork(pm::CollectorHAL *collector) return 1; } rc = collector->getRawHostNetworkLoad(NETIFNAME, &hostRxStart, &hostTxStart); - if (RT_FAILURE(rc)) + if (rc == VERR_NOT_IMPLEMENTED) + RTPrintf("tstCollector: getRawHostNetworkLoad() not implemented, skipping\n"); + else { - RTPrintf("tstCollector: getRawHostNetworkLoad() -> %Rrc\n", rc); - return 1; - } + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawHostNetworkLoad() -> %Rrc\n", rc); + return 1; + } - RTThreadSleep(5000); // Sleep for five seconds + RTThreadSleep(5000); // Sleep for five seconds - rc = collector->preCollect(hints, 0); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawHostNetworkLoad(NETIFNAME, &hostRxStop, &hostTxStop); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawHostNetworkLoad() -> %Rrc\n", rc); - return 1; + rc = collector->preCollect(hints, 0); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); + return 1; + } + hostRxStop = hostRxStart; + hostTxStop = hostTxStart; + rc = collector->getRawHostNetworkLoad(NETIFNAME, &hostRxStop, &hostTxStop); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawHostNetworkLoad() -> %Rrc\n", rc); + return 1; + } + RTPrintf("tstCollector: host network speed = %llu bytes/sec (%llu mbit/sec)\n", + speed, speed/(1000000/8)); + RTPrintf("tstCollector: host network rx = %llu bytes/sec (%llu mbit/sec, %u.%u %%)\n", + (hostRxStop - hostRxStart)/5, (hostRxStop - hostRxStart)/(5000000/8), + (hostRxStop - hostRxStart) * 100 / (speed * 5), + (hostRxStop - hostRxStart) * 10000 / (speed * 5) % 100); + RTPrintf("tstCollector: host network tx = %llu bytes/sec (%llu mbit/sec, %u.%u %%)\n\n", + (hostTxStop - hostTxStart)/5, (hostTxStop - hostTxStart)/(5000000/8), + (hostTxStop - hostTxStart) * 100 / (speed * 5), + (hostTxStop - hostTxStart) * 10000 / (speed * 5) % 100); } - RTPrintf("tstCollector: host network speed = %llu bytes/sec (%llu mbit/sec)\n", - speed, speed/(1000000/8)); - RTPrintf("tstCollector: host network rx = %llu bytes/sec (%llu mbit/sec, %u.%u %%)\n", - (hostRxStop - hostRxStart)/5, (hostRxStop - hostRxStart)/(5000000/8), - (hostRxStop - hostRxStart) * 100 / (speed * 5), - (hostRxStop - hostRxStart) * 10000 / (speed * 5) % 100); - RTPrintf("tstCollector: host network tx = %llu bytes/sec (%llu mbit/sec, %u.%u %%)\n\n", - (hostTxStop - hostTxStart)/5, (hostTxStop - hostTxStart)/(5000000/8), - (hostTxStop - hostTxStart) * 100 / (speed * 5), - (hostTxStop - hostTxStart) * 10000 / (speed * 5) % 100); return 0; } @@ -203,14 +211,19 @@ int testFsUsage(pm::CollectorHAL *collector) ULONG total, used, available; int rc = collector->getHostFilesystemUsage(FSNAME, &total, &used, &available); - if (RT_FAILURE(rc)) + if (rc == VERR_NOT_IMPLEMENTED) + RTPrintf("tstCollector: getHostFilesystemUsage() not implemented, skipping\n"); + else { - RTPrintf("tstCollector: getHostFilesystemUsage() -> %Rrc\n", rc); - return 1; + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getHostFilesystemUsage() -> %Rrc\n", rc); + return 1; + } + RTPrintf("tstCollector: host root fs total = %lu mB\n", total); + RTPrintf("tstCollector: host root fs used = %lu mB\n", used); + RTPrintf("tstCollector: host root fs available = %lu mB\n\n", available); } - RTPrintf("tstCollector: host root fs total = %lu mB\n", total); - RTPrintf("tstCollector: host root fs used = %lu mB\n", used); - RTPrintf("tstCollector: host root fs available = %lu mB\n\n", available); return 0; } @@ -220,54 +233,82 @@ int testDisk(pm::CollectorHAL *collector) uint64_t diskMsStart, totalMsStart; uint64_t diskMsStop, totalMsStop; - std::list disks; - int rc = pm::getDiskListByFs(FSNAME, disks); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getDiskListByFs(%s) -> %Rrc\n", FSNAME, rc); - return 1; - } - if (disks.empty()) + pm::DiskList disksUsage, disksLoad; + int rc = collector->getDiskListByFs(FSNAME, disksUsage, disksLoad); + if (rc == VERR_NOT_IMPLEMENTED) + RTPrintf("tstCollector: getDiskListByFs() not implemented, skipping\n"); + else { - RTPrintf("tstCollector: getDiskListByFs(%s) returned empty list\n", FSNAME); - return 1; - } - - RTPrintf("tstCollector: TESTING - Disk utilization, sleeping for 5 sec...\n"); - - hints.collectHostCpuLoad(); - rc = collector->preCollect(hints, 0); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawHostDiskLoad(disks.front().c_str(), &diskMsStart, &totalMsStart); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawHostNetworkLoad() -> %Rrc\n", rc); - return 1; - } + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getDiskListByFs(%s) -> %Rrc\n", FSNAME, rc); + return 1; + } + if (disksUsage.empty()) + { + RTPrintf("tstCollector: getDiskListByFs(%s) returned empty usage list\n", FSNAME); + return 1; + } + if (disksLoad.empty()) + { + RTPrintf("tstCollector: getDiskListByFs(%s) returned empty usage list\n", FSNAME); + return 1; + } - RTThreadSleep(5000); // Sleep for five seconds + pm::DiskList::iterator it; + for (it = disksUsage.begin(); it != disksUsage.end(); ++it) + { + uint64_t diskSize = 0; + rc = collector->getHostDiskSize(it->c_str(), &diskSize); + RTPrintf("tstCollector: TESTING - Disk size (%s) = %llu\n", it->c_str(), diskSize); + if (rc == VERR_FILE_NOT_FOUND) + RTPrintf("tstCollector: getHostDiskSize(%s) returned VERR_FILE_NOT_FOUND\n", it->c_str()); + else if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getHostDiskSize() -> %Rrc\n", rc); + return 1; + } + } - rc = collector->preCollect(hints, 0); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawHostDiskLoad(disks.front().c_str(), &diskMsStop, &totalMsStop); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawHostNetworkLoad() -> %Rrc\n", rc); - return 1; + for (it = disksLoad.begin(); it != disksLoad.end(); ++it) + { + RTPrintf("tstCollector: TESTING - Disk utilization (%s), sleeping for 5 s...\n", it->c_str()); + + hints.collectHostCpuLoad(); + rc = collector->preCollect(hints, 0); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); + return 1; + } + rc = collector->getRawHostDiskLoad(it->c_str(), &diskMsStart, &totalMsStart); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawHostDiskLoad() -> %Rrc\n", rc); + return 1; + } + + RTThreadSleep(5000); // Sleep for five seconds + + rc = collector->preCollect(hints, 0); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); + return 1; + } + rc = collector->getRawHostDiskLoad(it->c_str(), &diskMsStop, &totalMsStop); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawHostDiskLoad() -> %Rrc\n", rc); + return 1; + } + RTPrintf("tstCollector: host disk util = %llu msec (%u.%u %%), total = %llu msec\n\n", + (diskMsStop - diskMsStart), + (unsigned)((diskMsStop - diskMsStart) * 100 / (totalMsStop - totalMsStart)), + (unsigned)((diskMsStop - diskMsStart) * 10000 / (totalMsStop - totalMsStart) % 100), + totalMsStop - totalMsStart); + } } - RTPrintf("tstCollector: host disk util = %llu msec (%u.%u %%), total = %llu msec\n\n", - (diskMsStop - diskMsStart), - (unsigned)((diskMsStop - diskMsStart) * 100 / (totalMsStop - totalMsStart)), - (unsigned)((diskMsStop - diskMsStart) * 10000 / (totalMsStop - totalMsStart) % 100), - totalMsStop - totalMsStart); return 0; } @@ -276,6 +317,8 @@ int testDisk(pm::CollectorHAL *collector) int main(int argc, char *argv[]) { + bool cpuTest, ramTest, netTest, diskTest, fsTest, perfTest; + cpuTest = ramTest = netTest = diskTest = fsTest = perfTest = false; /* * Initialize the VBox runtime without loading * the support driver. @@ -286,12 +329,38 @@ int main(int argc, char *argv[]) RTPrintf("tstCollector: RTR3InitExe() -> %d\n", rc); return 1; } - if (argc > 1 && !strcmp(argv[1], "-child")) + if (argc > 1) { - /* We have spawned ourselves as a child process -- scratch the leg */ - RTThreadSleep(1000000); - return 1; + if (!strcmp(argv[1], "-child")) + { + /* We have spawned ourselves as a child process -- scratch the leg */ + RTThreadSleep(1000000); + return 1; + } + for (int i = 1; i < argc; i++) + { + if (!strcmp(argv[i], "-cpu")) + cpuTest = true; + else if (!strcmp(argv[i], "-ram")) + ramTest = true; + else if (!strcmp(argv[i], "-net")) + netTest = true; + else if (!strcmp(argv[i], "-disk")) + diskTest = true; + else if (!strcmp(argv[i], "-fs")) + fsTest = true; + else if (!strcmp(argv[i], "-perf")) + perfTest = true; + else + { + RTPrintf("tstCollector: Unknown option: %s\n", argv[i]); + return 2; + } + } } + else + cpuTest = ramTest = netTest = diskTest = fsTest = perfTest = true; + #ifdef RT_OS_WINDOWS HRESULT hRes = CoInitialize(NULL); /* @@ -313,12 +382,18 @@ int main(int argc, char *argv[]) RTPrintf("tstCollector: createMetricFactory() failed\n", rc); return 1; } -#if 1 + pm::CollectorHints hints; - hints.collectHostCpuLoad(); - hints.collectHostRamUsage(); - hints.collectProcessCpuLoad(RTProcSelf()); - hints.collectProcessRamUsage(RTProcSelf()); + if (cpuTest) + { + hints.collectHostCpuLoad(); + hints.collectProcessCpuLoad(RTProcSelf()); + } + if (ramTest) + { + hints.collectHostRamUsage(); + hints.collectProcessRamUsage(RTProcSelf()); + } uint64_t start; @@ -328,164 +403,164 @@ int main(int argc, char *argv[]) uint64_t processUserStart, processKernelStart, processTotalStart; uint64_t processUserStop, processKernelStop, processTotalStop; - RTPrintf("tstCollector: TESTING - CPU load, sleeping for 5 sec\n"); - rc = collector->preCollect(hints, 0); if (RT_FAILURE(rc)) { RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); return 1; } - rc = collector->getRawHostCpuLoad(&hostUserStart, &hostKernelStart, &hostIdleStart); - if (RT_FAILURE(rc)) + if (cpuTest) { - RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStart, &processKernelStart, &processTotalStart); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc); - return 1; - } + RTPrintf("tstCollector: TESTING - CPU load, sleeping for 5 s...\n"); + + rc = collector->getRawHostCpuLoad(&hostUserStart, &hostKernelStart, &hostIdleStart); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc); + return 1; + } + rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStart, &processKernelStart, &processTotalStart); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc); + return 1; + } - RTThreadSleep(5000); // Sleep for 5 seconds + RTThreadSleep(5000); // Sleep for 5 seconds - rc = collector->preCollect(hints, 0); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawHostCpuLoad(&hostUserStop, &hostKernelStop, &hostIdleStop); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStop, &processKernelStop, &processTotalStop); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc); - return 1; - } - hostTotal = hostUserStop - hostUserStart - + hostKernelStop - hostKernelStart - + hostIdleStop - hostIdleStart; - /*printf("tstCollector: host cpu user = %f sec\n", (hostUserStop - hostUserStart) / 10000000.); - printf("tstCollector: host cpu kernel = %f sec\n", (hostKernelStop - hostKernelStart) / 10000000.); - printf("tstCollector: host cpu idle = %f sec\n", (hostIdleStop - hostIdleStart) / 10000000.); - printf("tstCollector: host cpu total = %f sec\n", hostTotal / 10000000.);*/ - RTPrintf("tstCollector: host cpu user = %u.%u %%\n", - (unsigned)((hostUserStop - hostUserStart) * 100 / hostTotal), - (unsigned)((hostUserStop - hostUserStart) * 10000 / hostTotal % 100)); - RTPrintf("tstCollector: host cpu kernel = %u.%u %%\n", - (unsigned)((hostKernelStop - hostKernelStart) * 100 / hostTotal), - (unsigned)((hostKernelStop - hostKernelStart) * 10000 / hostTotal % 100)); - RTPrintf("tstCollector: host cpu idle = %u.%u %%\n", - (unsigned)((hostIdleStop - hostIdleStart) * 100 / hostTotal), - (unsigned)((hostIdleStop - hostIdleStart) * 10000 / hostTotal % 100)); - RTPrintf("tstCollector: process cpu user = %u.%u %%\n", - (unsigned)((processUserStop - processUserStart) * 100 / (processTotalStop - processTotalStart)), - (unsigned)((processUserStop - processUserStart) * 10000 / (processTotalStop - processTotalStart) % 100)); - RTPrintf("tstCollector: process cpu kernel = %u.%u %%\n\n", - (unsigned)((processKernelStop - processKernelStart) * 100 / (processTotalStop - processTotalStart)), - (unsigned)((processKernelStop - processKernelStart) * 10000 / (processTotalStop - processTotalStart) % 100)); - - RTPrintf("tstCollector: TESTING - CPU load, looping for 5 sec\n"); - rc = collector->preCollect(hints, 0); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawHostCpuLoad(&hostUserStart, &hostKernelStart, &hostIdleStart); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStart, &processKernelStart, &processTotalStart); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc); - return 1; - } - start = RTTimeMilliTS(); - while(RTTimeMilliTS() - start < 5000) - ; // Loop for 5 seconds - rc = collector->preCollect(hints, 0); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawHostCpuLoad(&hostUserStop, &hostKernelStop, &hostIdleStop); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc); - return 1; - } - rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStop, &processKernelStop, &processTotalStop); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc); - return 1; - } - hostTotal = hostUserStop - hostUserStart - + hostKernelStop - hostKernelStart - + hostIdleStop - hostIdleStart; - RTPrintf("tstCollector: host cpu user = %u.%u %%\n", - (unsigned)((hostUserStop - hostUserStart) * 100 / hostTotal), - (unsigned)((hostUserStop - hostUserStart) * 10000 / hostTotal % 100)); - RTPrintf("tstCollector: host cpu kernel = %u.%u %%\n", - (unsigned)((hostKernelStop - hostKernelStart) * 100 / hostTotal), - (unsigned)((hostKernelStop - hostKernelStart) * 10000 / hostTotal % 100)); - RTPrintf("tstCollector: host cpu idle = %u.%u %%\n", - (unsigned)((hostIdleStop - hostIdleStart) * 100 / hostTotal), - (unsigned)((hostIdleStop - hostIdleStart) * 10000 / hostTotal % 100)); - RTPrintf("tstCollector: process cpu user = %u.%u %%\n", - (unsigned)((processUserStop - processUserStart) * 100 / (processTotalStop - processTotalStart)), - (unsigned)((processUserStop - processUserStart) * 10000 / (processTotalStop - processTotalStart) % 100)); - RTPrintf("tstCollector: process cpu kernel = %u.%u %%\n\n", - (unsigned)((processKernelStop - processKernelStart) * 100 / (processTotalStop - processTotalStart)), - (unsigned)((processKernelStop - processKernelStart) * 10000 / (processTotalStop - processTotalStart) % 100)); - - RTPrintf("tstCollector: TESTING - Memory usage\n"); - - ULONG total, used, available, processUsed; - - rc = collector->getHostMemoryUsage(&total, &used, &available); - if (RT_FAILURE(rc)) - { - RTPrintf("tstCollector: getHostMemoryUsage() -> %Rrc\n", rc); - return 1; + rc = collector->preCollect(hints, 0); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); + return 1; + } + rc = collector->getRawHostCpuLoad(&hostUserStop, &hostKernelStop, &hostIdleStop); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc); + return 1; + } + rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStop, &processKernelStop, &processTotalStop); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc); + return 1; + } + hostTotal = hostUserStop - hostUserStart + + hostKernelStop - hostKernelStart + + hostIdleStop - hostIdleStart; + RTPrintf("tstCollector: host cpu user = %u.%u %%\n", + (unsigned)((hostUserStop - hostUserStart) * 100 / hostTotal), + (unsigned)((hostUserStop - hostUserStart) * 10000 / hostTotal % 100)); + RTPrintf("tstCollector: host cpu kernel = %u.%u %%\n", + (unsigned)((hostKernelStop - hostKernelStart) * 100 / hostTotal), + (unsigned)((hostKernelStop - hostKernelStart) * 10000 / hostTotal % 100)); + RTPrintf("tstCollector: host cpu idle = %u.%u %%\n", + (unsigned)((hostIdleStop - hostIdleStart) * 100 / hostTotal), + (unsigned)((hostIdleStop - hostIdleStart) * 10000 / hostTotal % 100)); + RTPrintf("tstCollector: process cpu user = %u.%u %%\n", + (unsigned)((processUserStop - processUserStart) * 100 / (processTotalStop - processTotalStart)), + (unsigned)((processUserStop - processUserStart) * 10000 / (processTotalStop - processTotalStart) % 100)); + RTPrintf("tstCollector: process cpu kernel = %u.%u %%\n\n", + (unsigned)((processKernelStop - processKernelStart) * 100 / (processTotalStop - processTotalStart)), + (unsigned)((processKernelStop - processKernelStart) * 10000 / (processTotalStop - processTotalStart) % 100)); + + RTPrintf("tstCollector: TESTING - CPU load, looping for 5 s...\n"); + rc = collector->preCollect(hints, 0); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); + return 1; + } + rc = collector->getRawHostCpuLoad(&hostUserStart, &hostKernelStart, &hostIdleStart); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc); + return 1; + } + rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStart, &processKernelStart, &processTotalStart); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc); + return 1; + } + start = RTTimeMilliTS(); + while (RTTimeMilliTS() - start < 5000) + ; // Loop for 5 seconds + rc = collector->preCollect(hints, 0); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: preCollect() -> %Rrc\n", rc); + return 1; + } + rc = collector->getRawHostCpuLoad(&hostUserStop, &hostKernelStop, &hostIdleStop); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawHostCpuLoad() -> %Rrc\n", rc); + return 1; + } + rc = collector->getRawProcessCpuLoad(RTProcSelf(), &processUserStop, &processKernelStop, &processTotalStop); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getRawProcessCpuLoad() -> %Rrc\n", rc); + return 1; + } + hostTotal = hostUserStop - hostUserStart + + hostKernelStop - hostKernelStart + + hostIdleStop - hostIdleStart; + RTPrintf("tstCollector: host cpu user = %u.%u %%\n", + (unsigned)((hostUserStop - hostUserStart) * 100 / hostTotal), + (unsigned)((hostUserStop - hostUserStart) * 10000 / hostTotal % 100)); + RTPrintf("tstCollector: host cpu kernel = %u.%u %%\n", + (unsigned)((hostKernelStop - hostKernelStart) * 100 / hostTotal), + (unsigned)((hostKernelStop - hostKernelStart) * 10000 / hostTotal % 100)); + RTPrintf("tstCollector: host cpu idle = %u.%u %%\n", + (unsigned)((hostIdleStop - hostIdleStart) * 100 / hostTotal), + (unsigned)((hostIdleStop - hostIdleStart) * 10000 / hostTotal % 100)); + RTPrintf("tstCollector: process cpu user = %u.%u %%\n", + (unsigned)((processUserStop - processUserStart) * 100 / (processTotalStop - processTotalStart)), + (unsigned)((processUserStop - processUserStart) * 10000 / (processTotalStop - processTotalStart) % 100)); + RTPrintf("tstCollector: process cpu kernel = %u.%u %%\n\n", + (unsigned)((processKernelStop - processKernelStart) * 100 / (processTotalStop - processTotalStart)), + (unsigned)((processKernelStop - processKernelStart) * 10000 / (processTotalStop - processTotalStart) % 100)); } - rc = collector->getProcessMemoryUsage(RTProcSelf(), &processUsed); - if (RT_FAILURE(rc)) + + if (ramTest) { - RTPrintf("tstCollector: getProcessMemoryUsage() -> %Rrc\n", rc); - return 1; + RTPrintf("tstCollector: TESTING - Memory usage\n"); + + ULONG total, used, available, processUsed; + + rc = collector->getHostMemoryUsage(&total, &used, &available); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getHostMemoryUsage() -> %Rrc\n", rc); + return 1; + } + rc = collector->getProcessMemoryUsage(RTProcSelf(), &processUsed); + if (RT_FAILURE(rc)) + { + RTPrintf("tstCollector: getProcessMemoryUsage() -> %Rrc\n", rc); + return 1; + } + RTPrintf("tstCollector: host mem total = %lu kB\n", total); + RTPrintf("tstCollector: host mem used = %lu kB\n", used); + RTPrintf("tstCollector: host mem available = %lu kB\n", available); + RTPrintf("tstCollector: process mem used = %lu kB\n\n", processUsed); } - RTPrintf("tstCollector: host mem total = %lu kB\n", total); - RTPrintf("tstCollector: host mem used = %lu kB\n", used); - RTPrintf("tstCollector: host mem available = %lu kB\n", available); - RTPrintf("tstCollector: process mem used = %lu kB\n\n", processUsed); -#endif -#if 1 - rc = testNetwork(collector); -#endif -#if 1 + + if (netTest) + rc = testNetwork(collector); + if (fsTest) rc = testFsUsage(collector); -#endif -#if 1 - rc = testDisk(collector); -#endif -#if 1 - RTPrintf("tstCollector: TESTING - Performance\n\n"); + if (diskTest) + rc = testDisk(collector); + if (perfTest) + { + RTPrintf("tstCollector: TESTING - Performance\n\n"); - measurePerformance(collector, argv[0], 100); -#endif + measurePerformance(collector, argv[0], 100); + } delete collector; diff --git a/src/VBox/Main/testcase/tstGuestCtrlContextID.cpp b/src/VBox/Main/testcase/tstGuestCtrlContextID.cpp index d7d74874..c9780a1d 100644 --- a/src/VBox/Main/testcase/tstGuestCtrlContextID.cpp +++ b/src/VBox/Main/testcase/tstGuestCtrlContextID.cpp @@ -34,7 +34,7 @@ using namespace com; int main() { RTTEST hTest; - int rc = RTTestInitAndCreate("tstMakeup", &hTest); + int rc = RTTestInitAndCreate("tstGuestCtrlContextID", &hTest); if (rc) return rc; RTTestBanner(hTest); @@ -51,11 +51,32 @@ int main() * -- we rely on the return values in the test(s) below. */ RTAssertSetQuiet(true); +#if 0 + for (int t = 0; t < 4 && !RTTestErrorCount(hTest); t++) + { + uint32_t uSession = RTRandU32Ex(0, VBOX_GUESTCTRL_MAX_SESSIONS - 1); + uint32_t uFilter = VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSession); + RTTestIPrintf(RTTESTLVL_INFO, "Session: %RU32, Filter: %x\n", uSession, uFilter); + + uint32_t uSession2 = RTRandU32Ex(0, VBOX_GUESTCTRL_MAX_SESSIONS - 1); + uint32_t uCID = VBOX_GUESTCTRL_CONTEXTID_MAKE(uSession2, + RTRandU32Ex(0, VBOX_GUESTCTRL_MAX_OBJECTS - 1), + RTRandU32Ex(0, VBOX_GUESTCTRL_MAX_CONTEXTS - 1)); + RTTestIPrintf(RTTESTLVL_INFO, "CID: %x (Session: %d), Masked: %x\n", + uCID, VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uCID), uCID & uFilter); + if ((uCID & uFilter) == uCID) + { + RTTestIPrintf(RTTESTLVL_INFO, "=========== Masking works: %x vs. %x\n", + uCID & uFilter, uFilter); + } + } +#endif + uint32_t uContextMax = UINT32_MAX; RTTestIPrintf(RTTESTLVL_DEBUG, "Max context is: %RU32\n", uContextMax); - /* Do 64 tests total. */ - for (int t = 0; t < 64 && !RTTestErrorCount(hTest); t++) + /* Do 4048 tests total. */ + for (int t = 0; t < 4048 && !RTTestErrorCount(hTest); t++) { /* VBOX_GUESTCTRL_MAX_* includes 0 as an object, so subtract one. */ uint32_t s = RTRandU32Ex(0, VBOX_GUESTCTRL_MAX_SESSIONS - 1); diff --git a/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp b/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp index 64dda854..93019a8c 100644 --- a/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp +++ b/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Main/testcase/tstMediumLock.cpp b/src/VBox/Main/testcase/tstMediumLock.cpp new file mode 100644 index 00000000..2aebc845 --- /dev/null +++ b/src/VBox/Main/testcase/tstMediumLock.cpp @@ -0,0 +1,299 @@ +/* $Id: tstMediumLock.cpp $ */ + +/** @file + * + * Medium lock test cases. + */ + +/* + * Copyright (C) 2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +#define LOG_ENABLED +#define LOG_GROUP LOG_GROUP_MAIN +#define LOG_INSTANCE NULL +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace com; + + +#define TEST_RT_SUCCESS(x,y,z) \ + do \ + { \ + int rc = (y); \ + if (RT_FAILURE(rc)) \ + RTTestFailed((x), "%s %Rrc", (z), rc); \ + } while (0) + +#define TEST_COM_SUCCESS(x,y,z) \ + do \ + { \ + HRESULT hrc = (y); \ + if (FAILED(hrc)) \ + RTTestFailed((x), "%s %Rhrc", (z), hrc); \ + } while (0) + +#define TEST_COM_FAILURE(x,y,z) \ + do \ + { \ + HRESULT hrc = (y); \ + if (SUCCEEDED(hrc)) \ + RTTestFailed((x), "%s", (z)); \ + } while (0) + +int main(int argc, char *argv[]) +{ + /* Init the runtime without loading the support driver. */ + RTR3InitExe(argc, &argv, 0); + + RTTEST hTest; + RTEXITCODE rcExit = RTTestInitAndCreate("tstMediumLock", &hTest); + if (rcExit) + return rcExit; + RTTestBanner(hTest); + + bool fComInit = false; + ComPtr pVirtualBox; + char szPathTemp[RTPATH_MAX] = ""; + ComPtr pMedium; + + if (!RTTestSubErrorCount(hTest)) + { + RTTestSub(hTest, "Constructing temp image name"); + TEST_RT_SUCCESS(hTest, RTPathTemp(szPathTemp, sizeof(szPathTemp)), "temp directory"); + RTUUID uuid; + RTUuidCreate(&uuid); + char szFile[50]; + RTStrPrintf(szFile, sizeof(szFile), "%RTuuid.vdi", &uuid); + TEST_RT_SUCCESS(hTest, RTPathAppend(szPathTemp, sizeof(szPathTemp), szFile), "concatenate image name"); + } + + if (!RTTestSubErrorCount(hTest)) + { + RTTestSub(hTest, "Initializing COM"); + TEST_COM_SUCCESS(hTest, Initialize(), "init"); + } + + if (!RTTestSubErrorCount(hTest)) + { + fComInit = true; + + RTTestSub(hTest, "Getting VirtualBox reference"); + TEST_COM_SUCCESS(hTest, pVirtualBox.createLocalObject(CLSID_VirtualBox), "vbox reference"); + } + + if (!RTTestSubErrorCount(hTest)) + { + RTTestSub(hTest, "Creating temp hard disk medium"); + TEST_COM_SUCCESS(hTest, pVirtualBox->CreateHardDisk(Bstr("VDI").raw(), Bstr(szPathTemp).raw(), pMedium.asOutParam()), "create medium"); + if (!pMedium.isNull()) + { + ComPtr pProgress; + SafeArray variant; + variant.push_back(MediumVariant_Standard); + TEST_COM_SUCCESS(hTest, pMedium->CreateBaseStorage(_1M, ComSafeArrayAsInParam(variant), pProgress.asOutParam()), "create base storage"); + if (!pProgress.isNull()) + TEST_COM_SUCCESS(hTest, pProgress->WaitForCompletion(30000), "waiting for completion of create"); + } + } + + if (!RTTestSubErrorCount(hTest)) + { + RTTestSub(hTest, "Write locks"); + ComPtr pToken1, pToken2; + + MediumState_T mediumState = MediumState_NotCreated; + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state"); + if (mediumState != MediumState_Created) + RTTestFailed(hTest, "wrong medium state %d", mediumState); + + TEST_COM_SUCCESS(hTest, pMedium->LockWrite(pToken1.asOutParam()), "write lock"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting lock write state"); + if (mediumState != MediumState_LockedWrite) + RTTestFailed(hTest, "wrong lock write medium state %d", mediumState); + + TEST_COM_FAILURE(hTest, pMedium->LockWrite(pToken2.asOutParam()), "nested write lock succeeded"); + if (!pToken2.isNull()) + RTTestFailed(hTest, "pToken2 is not null"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock write state"); + if (mediumState != MediumState_LockedWrite) + RTTestFailed(hTest, "wrong after nested lock write medium state %d", mediumState); + + if (!pToken1.isNull()) + TEST_COM_SUCCESS(hTest, pToken1->Abandon(), "write unlock"); + else + RTTestFailed(hTest, "pToken1 is null"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting unlock write state"); + if (mediumState != MediumState_Created) + RTTestFailed(hTest, "wrong unlock write medium state %d", mediumState); + } + + if (!RTTestSubErrorCount(hTest)) + { + RTTestSub(hTest, "Read locks"); + ComPtr pToken1, pToken2; + + MediumState_T mediumState = MediumState_NotCreated; + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state"); + if (mediumState != MediumState_Created) + RTTestFailed(hTest, "wrong medium state %d", mediumState); + + TEST_COM_SUCCESS(hTest, pMedium->LockRead(pToken1.asOutParam()), "read lock"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting lock read state"); + if (mediumState != MediumState_LockedRead) + RTTestFailed(hTest, "wrong lock read medium state %d", mediumState); + + TEST_COM_SUCCESS(hTest, pMedium->LockRead(pToken2.asOutParam()), "nested read lock failed"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock read state"); + if (mediumState != MediumState_LockedRead) + RTTestFailed(hTest, "wrong after nested lock read medium state %d", mediumState); + + if (!pToken2.isNull()) + TEST_COM_SUCCESS(hTest, pToken2->Abandon(), "read nested unlock"); + else + RTTestFailed(hTest, "pToken2 is null"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock read state"); + if (mediumState != MediumState_LockedRead) + RTTestFailed(hTest, "wrong after nested lock read medium state %d", mediumState); + + if (!pToken1.isNull()) + TEST_COM_SUCCESS(hTest, pToken1->Abandon(), "read nested unlock"); + else + RTTestFailed(hTest, "pToken1 is null"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting unlock read state"); + if (mediumState != MediumState_Created) + RTTestFailed(hTest, "wrong unlock read medium state %d", mediumState); + } + + if (!RTTestSubErrorCount(hTest)) + { + RTTestSub(hTest, "Mixing write and read locks"); + ComPtr pToken1, pToken2; + + MediumState_T mediumState = MediumState_NotCreated; + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state"); + if (mediumState != MediumState_Created) + RTTestFailed(hTest, "wrong medium state %d", mediumState); + + TEST_COM_SUCCESS(hTest, pMedium->LockWrite(pToken1.asOutParam()), "write lock"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting lock write state"); + if (mediumState != MediumState_LockedWrite) + RTTestFailed(hTest, "wrong lock write medium state %d", mediumState); + + TEST_COM_FAILURE(hTest, pMedium->LockRead(pToken2.asOutParam()), "write+read lock succeeded"); + if (!pToken2.isNull()) + RTTestFailed(hTest, "pToken2 is not null"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock write state"); + if (mediumState != MediumState_LockedWrite) + RTTestFailed(hTest, "wrong after nested lock write medium state %d", mediumState); + + if (!pToken1.isNull()) + TEST_COM_SUCCESS(hTest, pToken1->Abandon(), "write unlock"); + else + RTTestFailed(hTest, "pToken1 is null"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting unlock write state"); + if (mediumState != MediumState_Created) + RTTestFailed(hTest, "wrong unlock write medium state %d", mediumState); + } + + if (!RTTestSubErrorCount(hTest)) + { + RTTestSub(hTest, "Mixing read and write locks"); + ComPtr pToken1, pToken2; + + MediumState_T mediumState = MediumState_NotCreated; + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state"); + if (mediumState != MediumState_Created) + RTTestFailed(hTest, "wrong medium state %d", mediumState); + + TEST_COM_SUCCESS(hTest, pMedium->LockRead(pToken1.asOutParam()), "read lock"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting lock read state"); + if (mediumState != MediumState_LockedRead) + RTTestFailed(hTest, "wrong lock read medium state %d", mediumState); + + TEST_COM_FAILURE(hTest, pMedium->LockWrite(pToken2.asOutParam()), "read+write lock succeeded"); + if (!pToken2.isNull()) + RTTestFailed(hTest, "pToken2 is not null"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting after nested lock read state"); + if (mediumState != MediumState_LockedRead) + RTTestFailed(hTest, "wrong after nested lock read medium state %d", mediumState); + + if (!pToken1.isNull()) + TEST_COM_SUCCESS(hTest, pToken1->Abandon(), "read unlock"); + else + RTTestFailed(hTest, "pToken1 is null"); + + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting unlock read state"); + if (mediumState != MediumState_Created) + RTTestFailed(hTest, "wrong unlock read medium state %d", mediumState); + } + + /* Cleanup, also part of the testcase */ + + if (!pMedium.isNull()) + { + RTTestSub(hTest, "Closing medium"); + MediumState_T mediumState = MediumState_NotCreated; + TEST_COM_SUCCESS(hTest, pMedium->COMGETTER(State)(&mediumState), "getting state"); + if (mediumState == MediumState_Created) + { + ComPtr pProgress; + TEST_COM_SUCCESS(hTest, pMedium->DeleteStorage(pProgress.asOutParam()), "deleting storage"); + if (!pProgress.isNull()) + TEST_COM_SUCCESS(hTest, pProgress->WaitForCompletion(30000), "waiting for completion of delete"); + } + TEST_COM_SUCCESS(hTest, pMedium->Close(), "closing"); + pMedium.setNull(); + } + + pVirtualBox.setNull(); + + /* Make sure that there are no object references alive here, XPCOM does + * a very bad job at cleaning up such leftovers, spitting out warning + * messages in a debug build. */ + + if (fComInit) + { + RTTestIPrintf(RTTESTLVL_DEBUG, "Shutting down COM...\n"); + Shutdown(); + } + + /* + * Summary. + */ + return RTTestSummaryAndDestroy(hTest); +} diff --git a/src/VBox/Main/testcase/tstMouseImpl.cpp b/src/VBox/Main/testcase/tstMouseImpl.cpp new file mode 100644 index 00000000..361daf14 --- /dev/null +++ b/src/VBox/Main/testcase/tstMouseImpl.cpp @@ -0,0 +1,459 @@ +/* $Id: tstMouseImpl.cpp $ */ +/** @file + * Main unit test - Mouse class. + */ + +/* + * Copyright (C) 2011-2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +/****************************************************************************** +* Header Files * +******************************************************************************/ +#define IN_VMM_R3 /* Kill most Windows warnings on CFGMR3* implementations. */ +#include "MouseImpl.h" +#include "VMMDev.h" +#include "DisplayImpl.h" + +#include +#include +#include +#include +#include + +#ifndef RT_OS_WINDOWS +NS_DECL_CLASSINFO(Mouse) +NS_IMPL_THREADSAFE_ISUPPORTS1_CI(Mouse, IMouse) +#endif + +PDMIVMMDEVPORT VMMDevPort; + +class TestVMMDev : public VMMDevMouseInterface +{ + PPDMIVMMDEVPORT getVMMDevPort(void) { return &VMMDevPort; } +}; + +class TestDisplay : public DisplayMouseInterface +{ + void getFramebufferDimensions(int32_t *px1, int32_t *py1, + int32_t *px2, int32_t *py2); + int getScreenResolution(uint32_t cScreen, ULONG *pcx, ULONG *pcy, + ULONG *pcBPP, LONG *pXOrigin, LONG *pYOrigin); +}; + +class TestConsole : public ConsoleMouseInterface +{ +public: + VMMDevMouseInterface *getVMMDevMouseInterface() { return &mVMMDev; } + DisplayMouseInterface *getDisplayMouseInterface() { return &mDisplay; } + /** @todo why on earth is this not implemented? */ + void onMouseCapabilityChange(BOOL supportsAbsolute, BOOL supportsRelative, + BOOL supportsMT, BOOL needsHostCursor) {} + +private: + TestVMMDev mVMMDev; + TestDisplay 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, + NULL, /* pfnDetach */ + NULL, /* pfnDetachSelf */ + NULL, /* pfnMountPrepare */ + NULL, /* pfnAssertEMT */ + NULL, /* pfnAssertOther */ + NULL, /* pfnVMSetError */ + NULL, /* pfnVMSetErrorV */ + NULL, /* pfnVMSetRuntimeError */ + NULL, /* pfnVMSetRuntimeErrorV */ + NULL, /* pfnVMState */ + NULL, /* pfnVMTeleportedAndNotFullyResumedYet */ + NULL, /* pfnGetSupDrvSession */ + NULL, /* pfnQueueCreate */ + NULL, /* pfnTMGetVirtualFreq */ + NULL, /* pfnTMGetVirtualTime */ + NULL, /* pfnTMTimerCreate */ + NULL, /* pfnSSMRegister */ + NULL, /* pfnSSMDeregister */ + NULL, /* pfnDBGFInfoRegister */ + NULL, /* pfnDBGFInfoDeregister */ + NULL, /* pfnSTAMRegister */ + NULL, /* pfnSTAMRegisterF */ + NULL, /* pfnSTAMRegisterV */ + NULL, /* pfnSTAMDeregister */ + NULL, /* pfnSUPCallVMMR0Ex */ + NULL, /* pfnUSBRegisterHub */ + NULL, /* pfnSetAsyncNotification */ + NULL, /* pfnAsyncNotificationCompleted */ + NULL, /* pfnThreadCreate */ + NULL, /* pfnAsyncCompletionTemplateCreate */ +#ifdef VBOX_WITH_NETSHAPER + NULL, /* pfnNetShaperAttach */ + NULL, /* pfnNetShaperDetach */ +#endif + NULL, /* pfnLdrGetRCInterfaceSymbols */ + NULL, /* pfnLdrGetR0InterfaceSymbols */ + NULL, /* pfnCritSectInit */ + NULL, /* pfnCallR0 */ + NULL, /* pfnFTSetCheckpoint */ + NULL, /* pfnBlkCacheRetain */ + NULL, /* pfnVMGetSuspendReason */ + NULL, /* pfnVMGetResumeReason */ + NULL, /* pfnReserved0 */ + NULL, /* pfnReserved1 */ + NULL, /* pfnReserved2 */ + NULL, /* pfnReserved3 */ + NULL, /* pfnReserved4 */ + NULL, /* pfnReserved5 */ + NULL, /* pfnReserved6 */ + NULL, /* pfnReserved7 */ + NULL, /* pfnReserved8 */ + NULL, /* pfnReserved9 */ + PDM_DRVHLPR3_VERSION /* u32TheEnd */ +}; + +static struct +{ + int32_t dx; + int32_t dy; + int32_t dz; + int32_t dw; +} mouseEvent; + +static int mousePutEvent(PPDMIMOUSEPORT pInterface, int32_t iDeltaX, + int32_t iDeltaY, int32_t iDeltaZ, int32_t iDeltaW, + uint32_t fButtonStates) +{ + mouseEvent.dx = iDeltaX; + mouseEvent.dy = iDeltaY; + mouseEvent.dz = iDeltaZ; + mouseEvent.dw = iDeltaW; + return VINF_SUCCESS; +} + +static struct +{ + uint32_t cx; + uint32_t cy; + int32_t dz; + int32_t dw; + uint32_t fButtonStates; +} mouseEventAbs; + +static int mousePutEventAbs(PPDMIMOUSEPORT pInterface, uint32_t uX, + uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW, + uint32_t fButtonStates) +{ + mouseEventAbs.cx = uX; + mouseEventAbs.cy = uY; + mouseEventAbs.dz = iDeltaZ; + mouseEventAbs.dw = iDeltaW; + mouseEventAbs.fButtonStates = fButtonStates; + return VINF_SUCCESS; +} + +static struct PDMIMOUSEPORT pdmiMousePort = +{ + mousePutEvent, + mousePutEventAbs, + NULL /* pfnPutEventMT */ +}; + +static void *pdmiBaseQuery(struct PDMIBASE *pInterface, const char *pszIID) +{ + return &pdmiMousePort; +} + +static struct PDMIBASE pdmiBase = +{ + pdmiBaseQuery +}; + +static struct PDMDRVINS pdmdrvInsCore = +{ + PDM_DRVINS_VERSION, + 0, /* iInstance */ + NIL_RTRCPTR, /* pHlpRC */ + NIL_RTRCPTR, /* pvInstanceDataRC */ + NIL_RTR0PTR, /* pHelpR0 */ + NIL_RTR0PTR, /* pvInstanceDataR0 */ + &pdmHlpR3, + NULL, /* pvInstanceDataR3 */ + NIL_RTR3PTR, /* pReg */ + NIL_RTR3PTR, /* pCfg */ + &pdmiBase, + NULL, /* pDownBase */ + { /* IBase */ + NULL /* pfnQueryInterface */ + }, + 0, /* fTracing */ + 0, /* idTracing */ +#if HC_ARCH_BITS == 32 + { 0 }, /* au32Padding */ +#endif + { + { 0 } /* padding */ + }, /* Internal */ + { 0 } /* achInstanceData */ +}; + +static struct PDMDRVINS *ppdmdrvIns = NULL; + +ComObjPtr pMouse; +ConsoleMouseInterface *pConsole = NULL; + +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; +} + +void TestDisplay::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; +} + +int TestDisplay::getScreenResolution(uint32_t cScreen, ULONG *pcx, + ULONG *pcy, ULONG *pcBPP, LONG *pXOrigin, LONG *pYOrigin) +{ + NOREF(cScreen); + if (pcx) + *pcx = 640; + if (pcy) + *pcy = 480; + if (pcBPP) + *pcBPP = 32; + if (pXOrigin) + *pXOrigin = 0; + if (pYOrigin) + *pYOrigin = 0; + return S_OK; +} + +/****************************************************************************** +* Main test code * +******************************************************************************/ + +static int setup(void) +{ + PCFGMNODE pCfg = NULL; + Mouse *pMouse2; + int rc = VERR_NO_MEMORY; + VMMDevPort.pfnSetAbsoluteMouse = setAbsoluteMouse; + VMMDevPort.pfnUpdateMouseCapabilities = updateMouseCapabilities; + HRESULT hrc = pMouse.createObject(); + AssertComRC(hrc); + if (FAILED(hrc)) + return VERR_GENERAL_FAILURE; + pConsole = new TestConsole; + pMouse->init(pConsole); + ppdmdrvIns = (struct PDMDRVINS *) RTMemAllocZ( sizeof(struct PDMDRVINS) + + Mouse::DrvReg.cbInstance); + *ppdmdrvIns = pdmdrvInsCore; + pMouse2 = pMouse; + pCfg = CFGMR3CreateTree(NULL); + if (pCfg) + { + rc = CFGMR3InsertInteger(pCfg, "Object", (uintptr_t)pMouse2); + if (RT_SUCCESS(rc)) + Mouse::DrvReg.pfnConstruct(ppdmdrvIns, pCfg, 0); + } + return rc; +} + +static void teardown(void) +{ + pMouse.setNull(); + if (pConsole) + delete pConsole; + if (ppdmdrvIns) + 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, 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, 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, false); + pMouse->onVMMDevGuestCapsChange(VMMDEV_MOUSE_NEW_PROTOCOL); + pMouse->PutMouseEventAbsolute(0, 0, 0, 0, 0); + RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cx, 0x8000, 200), + ("mouseEventAbs.cx=%d\n", mouseEventAbs.cx)); + RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cy, 0x8000, 200), + ("mouseEventAbs.cy=%d\n", mouseEventAbs.cy)); + pMouse->PutMouseEventAbsolute(-319, -239, 0, 0, 3); + RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cx, 0, 200), + ("mouseEventAbs.cx=%d\n", mouseEventAbs.cx)); + RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cy, 0, 200), + ("mouseEventAbs.cy=%d\n", mouseEventAbs.cy)); + RTTESTI_CHECK_MSG(mouseEventAbs.fButtonStates == 3, + ("mouseEventAbs.fButtonStates=%u\n", + (unsigned) mouseEventAbs.fButtonStates)); + pMouse->PutMouseEventAbsolute(320, 240, -3, 2, 1); + RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cx, 0xffff, 200), + ("mouseEventAbs.cx=%d\n", mouseEventAbs.cx)); + RTTESTI_CHECK_MSG(approxEq(mouseEventAbs.cy, 0xffff, 200), + ("mouseEventAbs.cy=%d\n", mouseEventAbs.cy)); + RTTESTI_CHECK_MSG(mouseEventAbs.fButtonStates == 1, + ("mouseEventAbs.fButtonStates=%u\n", + (unsigned) mouseEventAbs.fButtonStates)); + RTTESTI_CHECK_MSG(mouseEventAbs.dz == -3, + ("mouseEventAbs.dz=%d\n", (int) mouseEvent.dz)); + RTTESTI_CHECK_MSG(mouseEventAbs.dw == 2, + ("mouseEventAbs.dw=%d\n", (int) mouseEvent.dw)); + mouseEventAbs.cx = mouseEventAbs.cy = 0xffff; + pMouse->PutMouseEventAbsolute(-640, -480, 0, 0, 0); + RTTESTI_CHECK_MSG(mouseEventAbs.cx == 0xffff, + ("mouseEventAbs.cx=%d\n", mouseEventAbs.cx)); + RTTESTI_CHECK_MSG(mouseEventAbs.cy == 0xffff, + ("mouseEventAbs.cy=%d\n", mouseEventAbs.cy)); + 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) + { + int rc = setup(); + AssertRC(rc); + if (RT_SUCCESS(rc)) + g_tests[i](hTest); + teardown(); + } + + /* + * Summary + */ + return RTTestSummaryAndDestroy(hTest); +} + diff --git a/src/VBox/Main/testcase/tstOVF.cpp b/src/VBox/Main/testcase/tstOVF.cpp index 9265b1e8..de8c808d 100644 --- a/src/VBox/Main/testcase/tstOVF.cpp +++ b/src/VBox/Main/testcase/tstOVF.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -116,12 +115,12 @@ void importOVF(const char *pcszPrefix, com::SafeArray aTypes; com::SafeArray aRefs; com::SafeArray aOvfValues; - com::SafeArray aVboxValues; + com::SafeArray aVBoxValues; com::SafeArray aExtraConfigValues; rc = pVSys->GetDescription(ComSafeArrayAsOutParam(aTypes), ComSafeArrayAsOutParam(aRefs), ComSafeArrayAsOutParam(aOvfValues), - ComSafeArrayAsOutParam(aVboxValues), + ComSafeArrayAsOutParam(aVBoxValues), ComSafeArrayAsOutParam(aExtraConfigValues)); if (FAILED(rc)) throw MyError(rc, "VirtualSystemDescription::GetDescription() failed\n"); @@ -226,7 +225,7 @@ void importOVF(const char *pcszPrefix, RTPrintf(" vsys %2u item %2u: type %2d (%s), ovf: \"%ls\", vbox: \"%ls\", extra: \"%ls\"\n", u, u2, t, pcszType, aOvfValues[u2], - aVboxValues[u2], + aVBoxValues[u2], aExtraConfigValues[u2]); } } @@ -305,10 +304,6 @@ int main(int argc, char *argv[]) rc = pSession.createInprocObject(CLSID_Session); if (FAILED(rc)) throw MyError(rc, "failed to create a session object!\n"); - // create the event queue - // (here it is necessary only to process remaining XPCOM/IPC events after the session is closed) - EventQueue eventQ; - // for each testcase, we will copy the dummy VMDK image to the subdirectory with the OVF testcase // so that the import will find the disks it expects; this is just for testing the import since // the imported machines will obviously not be usable. @@ -355,7 +350,7 @@ int main(int argc, char *argv[]) if (FAILED(rc)) throw MyError(rc, "Machine::Unregister() failed\n"); ComPtr pProgress; - rc = pMachine->Delete(ComSafeArrayAsInParam(sfaMedia), pProgress.asOutParam()); + rc = pMachine->DeleteConfig(ComSafeArrayAsInParam(sfaMedia), pProgress.asOutParam()); if (FAILED(rc)) throw MyError(rc, "Machine::DeleteSettings() 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 5a9491a4..e5e0eb56 100644 --- a/src/VBox/Main/testcase/tstUSBLinux.h +++ b/src/VBox/Main/testcase/tstUSBLinux.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * 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; diff --git a/src/VBox/Main/testcase/tstVBoxAPILinux.cpp b/src/VBox/Main/testcase/tstVBoxAPILinux.cpp deleted file mode 100644 index 4c4830ad..00000000 --- a/src/VBox/Main/testcase/tstVBoxAPILinux.cpp +++ /dev/null @@ -1,629 +0,0 @@ -/** @file - * - * tstVBoxAPILinux - sample program to illustrate the VirtualBox - * XPCOM API for machine management on Linux. - * It only uses standard C/C++ and XPCOM semantics, - * no additional VBox classes/macros/helpers. - */ - -/* - * Copyright (C) 2006-2012 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - */ - -/* - * PURPOSE OF THIS SAMPLE PROGRAM - * ------------------------------ - * - * This sample program is intended to demonstrate the minimal code necessary - * to use VirtualBox XPCOM API for learning puroses only. The program uses - * pure XPCOM and doesn't have any extra dependencies to let you better - * understand what is going on when a client talks to the VirtualBox core - * using the XPCOM framework. - * - * However, if you want to write a real application, it is highly recommended - * to use our MS COM XPCOM Glue library and helper C++ classes. This way, you - * will get at least the following benefits: - * - * a) better portability: both the MS COM (used on Windows) and XPCOM (used - * everywhere else) VirtualBox client application from the same source code - * (including common smart C++ templates for automatic interface pointer - * reference counter and string data management); - * b) simpler XPCOM initialization and shutdown (only a single method call - * that does everything right). - * - * Currently, there is no separate sample program that uses the VirtualBox MS - * COM XPCOM Glue library. Please refer to the sources of stock VirtualBox - * applications such as the VirtualBox GUI frontend or the VBoxManage command - * line frontend. - * - * - * RUNNING THIS SAMPLE PROGRAM - * --------------------------- - * - * This sample program needs to know where the VirtualBox core files reside - * and where to search for VirtualBox shared libraries. Therefore, you need to - * use the following (or similar) command to execute it: - * - * $ env VBOX_XPCOM_HOME=../../.. LD_LIBRARY_PATH=../../.. ./tstVBoxAPILinux - * - * The above command assumes that VBoxRT.so, VBoxXPCOM.so and others reside in - * the directory ../../.. - */ - - -#include -#include -#include - -/* - * Include the XPCOM headers - */ - -#if defined(XPCOM_GLUE) -#include -#endif - -#include -#include -#include -#include - -#include - -/* - * VirtualBox XPCOM interface. This header is generated - * from IDL which in turn is generated from a custom XML format. - */ -#include "VirtualBox_XPCOM.h" - -/* - * Prototypes - */ - -char *nsIDToString(nsID *guid); -void printErrorInfo(); - - -/** - * Display all registered VMs on the screen with some information about each - * - * @param virtualBox VirtualBox instance object. - */ -void listVMs(IVirtualBox *virtualBox) -{ - nsresult rc; - - printf("----------------------------------------------------\n"); - printf("VM List:\n\n"); - - /* - * Get the list of all registered VMs - */ - IMachine **machines = NULL; - PRUint32 machineCnt = 0; - - rc = virtualBox->GetMachines(&machineCnt, &machines); - if (NS_SUCCEEDED(rc)) - { - /* - * Iterate through the collection - */ - for (PRUint32 i = 0; i < machineCnt; ++ i) - { - IMachine *machine = machines[i]; - if (machine) - { - PRBool isAccessible = PR_FALSE; - machine->GetAccessible(&isAccessible); - - if (isAccessible) - { - nsXPIDLString machineName; - machine->GetName(getter_Copies(machineName)); - char *machineNameAscii = ToNewCString(machineName); - printf("\tName: %s\n", machineNameAscii); - free(machineNameAscii); - } - else - { - printf("\tName: \n"); - } - - nsXPIDLString iid; - machine->GetId(getter_Copies(iid)); - const char *uuidString = ToNewCString(iid); - printf("\tUUID: %s\n", uuidString); - free((void*)uuidString); - - if (isAccessible) - { - nsXPIDLString configFile; - machine->GetSettingsFilePath(getter_Copies(configFile)); - char *configFileAscii = ToNewCString(configFile); - printf("\tConfig file: %s\n", configFileAscii); - free(configFileAscii); - - PRUint32 memorySize; - machine->GetMemorySize(&memorySize); - printf("\tMemory size: %uMB\n", memorySize); - - nsXPIDLString typeId; - machine->GetOSTypeId(getter_Copies(typeId)); - IGuestOSType *osType = nsnull; - virtualBox->GetGuestOSType (typeId.get(), &osType); - nsXPIDLString osName; - osType->GetDescription(getter_Copies(osName)); - char *osNameAscii = ToNewCString(osName); - printf("\tGuest OS: %s\n\n", osNameAscii); - free(osNameAscii); - osType->Release(); - } - - /* don't forget to release the objects in the array... */ - machine->Release(); - } - } - } - printf("----------------------------------------------------\n\n"); -} - -/** - * Create a sample VM - * - * @param virtualBox VirtualBox instance object. - */ -void createVM(IVirtualBox *virtualBox) -{ - nsresult rc; - /* - * First create a unnamed new VM. It will be unconfigured and not be saved - * in the configuration until we explicitely choose to do so. - */ - nsCOMPtr machine; - rc = virtualBox->CreateMachine(NULL, /* settings file */ - NS_LITERAL_STRING("A brand new name").get(), - 0, nsnull, /* groups (safearray)*/ - nsnull, /* ostype */ - nsnull, /* create flags */ - getter_AddRefs(machine)); - if (NS_FAILED(rc)) - { - printf("Error: could not create machine! rc=%08X\n", rc); - return; - } - - /* - * Set some properties - */ - /* alternative to illustrate the use of string classes */ - rc = machine->SetName(NS_ConvertUTF8toUTF16("A new name").get()); - rc = machine->SetMemorySize(128); - - /* - * Now a more advanced property -- the guest OS type. This is - * an object by itself which has to be found first. Note that we - * use the ID of the guest OS type here which is an internal - * representation (you can find that by configuring the OS type of - * a machine in the GUI and then looking at the - * setting in the XML file. It is also possible to get the OS type from - * its description (win2k would be "Windows 2000") by getting the - * guest OS type collection and enumerating it. - */ - nsCOMPtr osType; - rc = virtualBox->GetGuestOSType(NS_LITERAL_STRING("win2k").get(), - getter_AddRefs(osType)); - if (NS_FAILED(rc)) - { - printf("Error: could not find guest OS type! rc=%08X\n", rc); - } - else - { - machine->SetOSTypeId (NS_LITERAL_STRING("win2k").get()); - } - - /* - * Register the VM. Note that this call also saves the VM config - * to disk. It is also possible to save the VM settings but not - * register the VM. - * - * Also note that due to current VirtualBox limitations, the machine - * must be registered *before* we can attach hard disks to it. - */ - rc = virtualBox->RegisterMachine(machine); - if (NS_FAILED(rc)) - { - printf("Error: could not register machine! rc=%08X\n", rc); - printErrorInfo(); - return; - } - - /* - * In order to manipulate the registered machine, we must open a session - * for that machine. Do it now. - */ - nsCOMPtr session; - { - nsCOMPtr manager; - rc = NS_GetComponentManager (getter_AddRefs (manager)); - if (NS_FAILED(rc)) - { - printf("Error: could not get component manager! rc=%08X\n", rc); - return; - } - rc = manager->CreateInstanceByContractID (NS_SESSION_CONTRACTID, - nsnull, - NS_GET_IID(ISession), - getter_AddRefs(session)); - if (NS_FAILED(rc)) - { - printf("Error, could not instantiate session object! rc=0x%x\n", rc); - return; - } - - rc = machine->LockMachine(session, LockType_Write); - if (NS_FAILED(rc)) - { - printf("Error, could not lock the machine for the session! rc=0x%x\n", rc); - return; - } - - /* - * After the machine is registered, the initial machine object becomes - * immutable. In order to get a mutable machine object, we must query - * it from the opened session object. - */ - rc = session->GetMachine(getter_AddRefs(machine)); - if (NS_FAILED(rc)) - { - printf("Error, could not get machine session! rc=0x%x\n", rc); - return; - } - } - - /* - * Create a virtual harddisk - */ - nsCOMPtr hardDisk = 0; - rc = virtualBox->CreateHardDisk(NS_LITERAL_STRING("VDI").get(), - NS_LITERAL_STRING("TestHardDisk.vdi").get(), - getter_AddRefs(hardDisk)); - if (NS_FAILED(rc)) - { - printf("Failed creating a hard disk object! rc=%08X\n", rc); - } - else - { - /* - * We have only created an object so far. No on disk representation exists - * because none of its properties has been set so far. Let's continue creating - * a dynamically expanding image. - */ - nsCOMPtr progress; - rc = hardDisk->CreateBaseStorage(100, // size in megabytes - MediumVariant_Standard, - getter_AddRefs(progress)); // optional progress object - if (NS_FAILED(rc)) - { - printf("Failed creating hard disk image! rc=%08X\n", rc); - } - else - { - /* - * Creating the image is done in the background because it can take quite - * some time (at least fixed size images). We have to wait for its completion. - * Here we wait forever (timeout -1) which is potentially dangerous. - */ - rc = progress->WaitForCompletion(-1); - PRInt32 resultCode; - progress->GetResultCode(&resultCode); - if (NS_FAILED(rc) || NS_FAILED(resultCode)) - { - printf("Error: could not create hard disk! rc=%08X\n", - NS_FAILED(rc) ? rc : resultCode); - } - else - { - /* - * Now that it's created, we can assign it to the VM. - */ - rc = machine->AttachDevice(NS_LITERAL_STRING("IDE Controller").get(), // controller identifier - 0, // channel number on the controller - 0, // device number on the controller - DeviceType_HardDisk, - hardDisk); - if (NS_FAILED(rc)) - { - printf("Error: could not attach hard disk! rc=%08X\n", rc); - } - } - } - } - - /* - * It's got a hard disk but that one is new and thus not bootable. Make it - * boot from an ISO file. This requires some processing. First the ISO file - * has to be registered and then mounted to the VM's DVD drive and selected - * as the boot device. - */ - nsCOMPtr dvdImage; - 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); - else - { - /* - * Now assign it to our VM - */ - rc = machine->MountMedium(NS_LITERAL_STRING("IDE Controller").get(), // controller identifier - 2, // channel number on the controller - 0, // device number on the controller - dvdImage, - PR_FALSE); // aForce - if (NS_FAILED(rc)) - { - printf("Error: could not mount ISO image! rc=%08X\n", rc); - } - else - { - /* - * Last step: tell the VM to boot from the CD. - */ - rc = machine->SetBootOrder (1, DeviceType::DVD); - if (NS_FAILED(rc)) - { - printf("Could not set boot device! rc=%08X\n", rc); - } - } - } - - /* - * Save all changes we've just made. - */ - rc = machine->SaveSettings(); - if (NS_FAILED(rc)) - { - printf("Could not save machine settings! rc=%08X\n", rc); - } - - /* - * It is always important to close the open session when it becomes not - * necessary any more. - */ - session->UnlockMachine(); -} - -// main -/////////////////////////////////////////////////////////////////////////////// - -int main(int argc, char *argv[]) -{ - /* - * Check that PRUnichar is equal in size to what compiler composes L"" - * strings from; otherwise NS_LITERAL_STRING macros won't work correctly - * and we will get a meaningless SIGSEGV. This, of course, must be checked - * at compile time in xpcom/string/nsTDependentString.h, but XPCOM lacks - * compile-time assert macros and I'm not going to add them now. - */ - if (sizeof(PRUnichar) != sizeof(wchar_t)) - { - printf("Error: sizeof(PRUnichar) {%lu} != sizeof(wchar_t) {%lu}!\n" - "Probably, you forgot the -fshort-wchar compiler option.\n", - (unsigned long) sizeof(PRUnichar), - (unsigned long) sizeof(wchar_t)); - return -1; - } - - nsresult rc; - - /* - * This is the standard XPCOM init procedure. - * What we do is just follow the required steps to get an instance - * of our main interface, which is IVirtualBox. - */ -#if defined(XPCOM_GLUE) - XPCOMGlueStartup(nsnull); -#endif - - /* - * Note that we scope all nsCOMPtr variables in order to have all XPCOM - * objects automatically released before we call NS_ShutdownXPCOM at the - * end. This is an XPCOM requirement. - */ - { - nsCOMPtr serviceManager; - rc = NS_InitXPCOM2(getter_AddRefs(serviceManager), nsnull, nsnull); - if (NS_FAILED(rc)) - { - printf("Error: XPCOM could not be initialized! rc=0x%x\n", rc); - return -1; - } - -#if 0 - /* - * Register our components. This step is only necessary if this executable - * implements XPCOM components itself which is not the case for this - * simple example. - */ - nsCOMPtr registrar = do_QueryInterface(serviceManager); - if (!registrar) - { - printf("Error: could not query nsIComponentRegistrar interface!\n"); - return -1; - } - registrar->AutoRegister(nsnull); -#endif - - /* - * Make sure the main event queue is created. This event queue is - * responsible for dispatching incoming XPCOM IPC messages. The main - * thread should run this event queue's loop during lengthy non-XPCOM - * operations to ensure messages from the VirtualBox server and other - * XPCOM IPC clients are processed. This use case doesn't perform such - * operations so it doesn't run the event loop. - */ - nsCOMPtr eventQ; - rc = NS_GetMainEventQ(getter_AddRefs (eventQ)); - if (NS_FAILED(rc)) - { - printf("Error: could not get main event queue! rc=%08X\n", rc); - return -1; - } - - /* - * Now XPCOM is ready and we can start to do real work. - * IVirtualBox is the root interface of VirtualBox and will be - * retrieved from the XPCOM component manager. We use the - * XPCOM provided smart pointer nsCOMPtr for all objects because - * that's very convenient and removes the need deal with reference - * counting and freeing. - */ - nsCOMPtr manager; - rc = NS_GetComponentManager (getter_AddRefs (manager)); - if (NS_FAILED(rc)) - { - printf("Error: could not get component manager! rc=%08X\n", rc); - return -1; - } - - nsCOMPtr virtualBox; - rc = manager->CreateInstanceByContractID (NS_VIRTUALBOX_CONTRACTID, - nsnull, - NS_GET_IID(IVirtualBox), - getter_AddRefs(virtualBox)); - if (NS_FAILED(rc)) - { - printf("Error, could not instantiate VirtualBox object! rc=0x%x\n", rc); - return -1; - } - printf("VirtualBox object created\n"); - - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - - - listVMs(virtualBox); - - createVM(virtualBox); - - - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - - /* this is enough to free the IVirtualBox instance -- smart pointers rule! */ - virtualBox = nsnull; - - /* - * Process events that might have queued up in the XPCOM event - * queue. If we don't process them, the server might hang. - */ - eventQ->ProcessPendingEvents(); - } - - /* - * Perform the standard XPCOM shutdown procedure. - */ - NS_ShutdownXPCOM(nsnull); -#if defined(XPCOM_GLUE) - XPCOMGlueShutdown(); -#endif - printf("Done!\n"); - return 0; -} - - -////////////////////////////////////////////////////////////////////////////////////////////////////// -//// Helpers -////////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * Helper function to convert an nsID into a human readable string - * - * @returns result string, allocated. Has to be freed using free() - * @param guid Pointer to nsID that will be converted. - */ -char *nsIDToString(nsID *guid) -{ - char *res = (char*)malloc(39); - - if (res != NULL) - { - snprintf(res, 39, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - guid->m0, (PRUint32)guid->m1, (PRUint32)guid->m2, - (PRUint32)guid->m3[0], (PRUint32)guid->m3[1], (PRUint32)guid->m3[2], - (PRUint32)guid->m3[3], (PRUint32)guid->m3[4], (PRUint32)guid->m3[5], - (PRUint32)guid->m3[6], (PRUint32)guid->m3[7]); - } - return res; -} - -/** - * Helper function to print XPCOM exception information set on the current - * thread after a failed XPCOM method call. This function will also print - * extended VirtualBox error info if it is available. - */ -void printErrorInfo() -{ - nsresult rc; - - nsCOMPtr es; - es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rc); - if (NS_SUCCEEDED(rc)) - { - nsCOMPtr em; - rc = es->GetCurrentExceptionManager (getter_AddRefs (em)); - if (NS_SUCCEEDED(rc)) - { - nsCOMPtr ex; - rc = em->GetCurrentException (getter_AddRefs (ex)); - if (NS_SUCCEEDED(rc) && ex) - { - nsCOMPtr info; - info = do_QueryInterface(ex, &rc); - if (NS_SUCCEEDED(rc) && info) - { - /* got extended error info */ - printf ("Extended error info (IVirtualBoxErrorInfo):\n"); - PRInt32 resultCode = NS_OK; - info->GetResultCode (&resultCode); - printf (" resultCode=%08X\n", resultCode); - nsXPIDLString component; - info->GetComponent (getter_Copies (component)); - printf (" component=%s\n", NS_ConvertUTF16toUTF8(component).get()); - nsXPIDLString text; - info->GetText (getter_Copies (text)); - printf (" text=%s\n", NS_ConvertUTF16toUTF8(text).get()); - } - else - { - /* got basic error info */ - printf ("Basic error info (nsIException):\n"); - nsresult resultCode = NS_OK; - ex->GetResult (&resultCode); - printf (" resultCode=%08X\n", resultCode); - nsXPIDLCString message; - ex->GetMessage (getter_Copies (message)); - printf (" message=%s\n", message.get()); - } - - /* reset the exception to NULL to indicate we've processed it */ - em->SetCurrentException (NULL); - - rc = NS_OK; - } - } - } -} diff --git a/src/VBox/Main/testcase/tstVBoxAPIWin.cpp b/src/VBox/Main/testcase/tstVBoxAPIWin.cpp index d3c0839c..6211e428 100644 --- a/src/VBox/Main/testcase/tstVBoxAPIWin.cpp +++ b/src/VBox/Main/testcase/tstVBoxAPIWin.cpp @@ -12,7 +12,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * 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; diff --git a/src/VBox/Main/testcase/tstVBoxAPIXPCOM.cpp b/src/VBox/Main/testcase/tstVBoxAPIXPCOM.cpp new file mode 100644 index 00000000..1ea16f62 --- /dev/null +++ b/src/VBox/Main/testcase/tstVBoxAPIXPCOM.cpp @@ -0,0 +1,655 @@ +/** @file + * + * tstVBoxAPILinux - sample program to illustrate the VirtualBox + * XPCOM API for machine management on Linux. + * It only uses standard C/C++ and XPCOM semantics, + * no additional VBox classes/macros/helpers. + */ + +/* + * Copyright (C) 2006-2014 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +/* + * PURPOSE OF THIS SAMPLE PROGRAM + * ------------------------------ + * + * This sample program is intended to demonstrate the minimal code necessary + * to use VirtualBox XPCOM API for learning puroses only. The program uses + * pure XPCOM and doesn't have any extra dependencies to let you better + * understand what is going on when a client talks to the VirtualBox core + * using the XPCOM framework. + * + * However, if you want to write a real application, it is highly recommended + * to use our MS COM XPCOM Glue library and helper C++ classes. This way, you + * will get at least the following benefits: + * + * a) better portability: both the MS COM (used on Windows) and XPCOM (used + * everywhere else) VirtualBox client application from the same source code + * (including common smart C++ templates for automatic interface pointer + * reference counter and string data management); + * b) simpler XPCOM initialization and shutdown (only a single method call + * that does everything right). + * + * Currently, there is no separate sample program that uses the VirtualBox MS + * COM XPCOM Glue library. Please refer to the sources of stock VirtualBox + * applications such as the VirtualBox GUI frontend or the VBoxManage command + * line frontend. + * + * + * RUNNING THIS SAMPLE PROGRAM + * --------------------------- + * + * This sample program needs to know where the VirtualBox core files reside + * and where to search for VirtualBox shared libraries. Therefore, you need to + * use the following (or similar) command to execute it: + * + * $ env VBOX_XPCOM_HOME=../../.. LD_LIBRARY_PATH=../../.. ./tstVBoxAPILinux + * + * The above command assumes that VBoxRT.so, VBoxXPCOM.so and others reside in + * the directory ../../.. + */ + + +#include +#include +#include + +/* + * Include the XPCOM headers + */ +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + + +/* + * VirtualBox XPCOM interface. This header is generated + * from IDL which in turn is generated from a custom XML format. + */ +#include "VirtualBox_XPCOM.h" + +/* + * Prototypes + */ + +char *nsIDToString(nsID *guid); +void printErrorInfo(); + + +/** + * Display all registered VMs on the screen with some information about each + * + * @param virtualBox VirtualBox instance object. + */ +void listVMs(IVirtualBox *virtualBox) +{ + nsresult rc; + + RTPrintf("----------------------------------------------------\n"); + RTPrintf("VM List:\n\n"); + + /* + * Get the list of all registered VMs + */ + IMachine **machines = NULL; + PRUint32 machineCnt = 0; + + rc = virtualBox->GetMachines(&machineCnt, &machines); + if (NS_SUCCEEDED(rc)) + { + /* + * Iterate through the collection + */ + for (PRUint32 i = 0; i < machineCnt; ++ i) + { + IMachine *machine = machines[i]; + if (machine) + { + PRBool isAccessible = PR_FALSE; + machine->GetAccessible(&isAccessible); + + if (isAccessible) + { + nsXPIDLString machineName; + machine->GetName(getter_Copies(machineName)); + char *machineNameAscii = ToNewCString(machineName); + RTPrintf("\tName: %s\n", machineNameAscii); + free(machineNameAscii); + } + else + { + RTPrintf("\tName: \n"); + } + + nsXPIDLString iid; + machine->GetId(getter_Copies(iid)); + const char *uuidString = ToNewCString(iid); + RTPrintf("\tUUID: %s\n", uuidString); + free((void*)uuidString); + + if (isAccessible) + { + nsXPIDLString configFile; + machine->GetSettingsFilePath(getter_Copies(configFile)); + char *configFileAscii = ToNewCString(configFile); + RTPrintf("\tConfig file: %s\n", configFileAscii); + free(configFileAscii); + + PRUint32 memorySize; + machine->GetMemorySize(&memorySize); + RTPrintf("\tMemory size: %uMB\n", memorySize); + + nsXPIDLString typeId; + machine->GetOSTypeId(getter_Copies(typeId)); + IGuestOSType *osType = nsnull; + virtualBox->GetGuestOSType (typeId.get(), &osType); + nsXPIDLString osName; + osType->GetDescription(getter_Copies(osName)); + char *osNameAscii = ToNewCString(osName); + RTPrintf("\tGuest OS: %s\n\n", osNameAscii); + free(osNameAscii); + osType->Release(); + } + + /* don't forget to release the objects in the array... */ + machine->Release(); + } + } + } + RTPrintf("----------------------------------------------------\n\n"); +} + +/** + * Create a sample VM + * + * @param virtualBox VirtualBox instance object. + */ +void createVM(IVirtualBox *virtualBox) +{ + nsresult rc; + /* + * First create a unnamed new VM. It will be unconfigured and not be saved + * in the configuration until we explicitely choose to do so. + */ + nsCOMPtr machine; + rc = virtualBox->CreateMachine(NULL, /* settings file */ + NS_LITERAL_STRING("A brand new name").get(), + 0, nsnull, /* groups (safearray)*/ + nsnull, /* ostype */ + nsnull, /* create flags */ + getter_AddRefs(machine)); + if (NS_FAILED(rc)) + { + RTPrintf("Error: could not create machine! rc=%Rhrc\n", rc); + return; + } + + /* + * Set some properties + */ + /* alternative to illustrate the use of string classes */ + rc = machine->SetName(NS_ConvertUTF8toUTF16("A new name").get()); + rc = machine->SetMemorySize(128); + + /* + * Now a more advanced property -- the guest OS type. This is + * an object by itself which has to be found first. Note that we + * use the ID of the guest OS type here which is an internal + * representation (you can find that by configuring the OS type of + * a machine in the GUI and then looking at the + * setting in the XML file. It is also possible to get the OS type from + * its description (win2k would be "Windows 2000") by getting the + * guest OS type collection and enumerating it. + */ + nsCOMPtr osType; + rc = virtualBox->GetGuestOSType(NS_LITERAL_STRING("Windows2000").get(), + getter_AddRefs(osType)); + if (NS_FAILED(rc)) + { + RTPrintf("Error: could not find guest OS type! rc=%Rhrc\n", rc); + } + else + { + machine->SetOSTypeId (NS_LITERAL_STRING("Windows2000").get()); + } + + /* + * Register the VM. Note that this call also saves the VM config + * to disk. It is also possible to save the VM settings but not + * register the VM. + * + * Also note that due to current VirtualBox limitations, the machine + * must be registered *before* we can attach hard disks to it. + */ + rc = virtualBox->RegisterMachine(machine); + if (NS_FAILED(rc)) + { + RTPrintf("Error: could not register machine! rc=%Rhrc\n", rc); + printErrorInfo(); + return; + } + + nsCOMPtr origMachine = machine; + + /* + * In order to manipulate the registered machine, we must open a session + * for that machine. Do it now. + */ + nsCOMPtr session; + nsCOMPtr sessionMachine; + { + nsCOMPtr manager; + rc = NS_GetComponentManager (getter_AddRefs (manager)); + if (NS_FAILED(rc)) + { + RTPrintf("Error: could not get component manager! rc=%Rhrc\n", rc); + return; + } + rc = manager->CreateInstanceByContractID (NS_SESSION_CONTRACTID, + nsnull, + NS_GET_IID(ISession), + getter_AddRefs(session)); + if (NS_FAILED(rc)) + { + RTPrintf("Error, could not instantiate session object! rc=%Rhrc\n", rc); + return; + } + + rc = machine->LockMachine(session, LockType_Write); + if (NS_FAILED(rc)) + { + RTPrintf("Error, could not lock the machine for the session! rc=%Rhrc\n", rc); + return; + } + + /* + * After the machine is registered, the initial machine object becomes + * immutable. In order to get a mutable machine object, we must query + * it from the opened session object. + */ + rc = session->GetMachine(getter_AddRefs(sessionMachine)); + if (NS_FAILED(rc)) + { + RTPrintf("Error, could not get machine session! rc=%Rhrc\n", rc); + return; + } + } + + /* + * Create a virtual harddisk + */ + nsCOMPtr hardDisk = 0; + rc = virtualBox->CreateHardDisk(NS_LITERAL_STRING("VDI").get(), + NS_LITERAL_STRING("TestHardDisk.vdi").get(), + getter_AddRefs(hardDisk)); + if (NS_FAILED(rc)) + { + RTPrintf("Failed creating a hard disk object! rc=%Rhrc\n", rc); + } + else + { + /* + * We have only created an object so far. No on disk representation exists + * because none of its properties has been set so far. Let's continue creating + * a dynamically expanding image. + */ + nsCOMPtr progress; + com::SafeArray mediumVariant; + mediumVariant.push_back(MediumVariant_Standard); + rc = hardDisk->CreateBaseStorage(100, // size in megabytes + ComSafeArrayAsInParam(mediumVariant), + getter_AddRefs(progress)); // optional progress object + if (NS_FAILED(rc)) + { + RTPrintf("Failed creating hard disk image! rc=%Rhrc\n", rc); + } + else + { + /* + * Creating the image is done in the background because it can take quite + * some time (at least fixed size images). We have to wait for its completion. + * Here we wait forever (timeout -1) which is potentially dangerous. + */ + rc = progress->WaitForCompletion(-1); + PRInt32 resultCode; + progress->GetResultCode(&resultCode); + if (NS_FAILED(rc) || NS_FAILED(resultCode)) + { + RTPrintf("Error: could not create hard disk! rc=%Rhrc\n", + NS_FAILED(rc) ? rc : resultCode); + } + else + { + /* + * Now that it's created, we can assign it to the VM. + */ + rc = sessionMachine->AttachDevice( + NS_LITERAL_STRING("IDE Controller").get(), // controller identifier + 0, // channel number on the controller + 0, // device number on the controller + DeviceType_HardDisk, + hardDisk); + if (NS_FAILED(rc)) + { + RTPrintf("Error: could not attach hard disk! rc=%Rhrc\n", rc); + } + } + } + } + + /* + * It's got a hard disk but that one is new and thus not bootable. Make it + * boot from an ISO file. This requires some processing. First the ISO file + * has to be registered and then mounted to the VM's DVD drive and selected + * as the boot device. + */ + nsCOMPtr dvdImage; + 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)) + RTPrintf("Error: could not open CD image! rc=%Rhrc\n", rc); + else + { + /* + * Now assign it to our VM + */ + rc = sessionMachine->MountMedium( + NS_LITERAL_STRING("IDE Controller").get(), // controller identifier + 2, // channel number on the controller + 0, // device number on the controller + dvdImage, + PR_FALSE); // aForce + if (NS_FAILED(rc)) + { + RTPrintf("Error: could not mount ISO image! rc=%Rhrc\n", rc); + } + else + { + /* + * Last step: tell the VM to boot from the CD. + */ + rc = sessionMachine->SetBootOrder (1, DeviceType::DVD); + if (NS_FAILED(rc)) + { + RTPrintf("Could not set boot device! rc=%Rhrc\n", rc); + } + } + } + + /* + * Save all changes we've just made. + */ + rc = sessionMachine->SaveSettings(); + if (NS_FAILED(rc)) + RTPrintf("Could not save machine settings! rc=%Rhrc\n", rc); + + /* + * It is always important to close the open session when it becomes not + * necessary any more. + */ + session->UnlockMachine(); + + com::SafeIfaceArray aMedia; + rc = machine->Unregister((CleanupMode_T)CleanupMode_DetachAllReturnHardDisksOnly, + ComSafeArrayAsOutParam(aMedia)); + if (NS_FAILED(rc)) + RTPrintf("Unregistering the machine failed! rc=%Rhrc\n", rc); + else + { + ComPtr pProgress; + rc = machine->DeleteConfig(ComSafeArrayAsInParam(aMedia), pProgress.asOutParam()); + if (NS_FAILED(rc)) + RTPrintf("Deleting of machine failed! rc=%Rhrc\n", rc); + else + { + rc = pProgress->WaitForCompletion(-1); + PRInt32 resultCode; + pProgress->GetResultCode(&resultCode); + if (NS_FAILED(rc) || NS_FAILED(resultCode)) + RTPrintf("Failed to delete the machine! rc=%Rhrc\n", + NS_FAILED(rc) ? rc : resultCode); + } + } +} + +// main +/////////////////////////////////////////////////////////////////////////////// + +int main(int argc, char *argv[]) +{ + /* + * Check that PRUnichar is equal in size to what compiler composes L"" + * strings from; otherwise NS_LITERAL_STRING macros won't work correctly + * and we will get a meaningless SIGSEGV. This, of course, must be checked + * at compile time in xpcom/string/nsTDependentString.h, but XPCOM lacks + * compile-time assert macros and I'm not going to add them now. + */ + if (sizeof(PRUnichar) != sizeof(wchar_t)) + { + RTPrintf("Error: sizeof(PRUnichar) {%lu} != sizeof(wchar_t) {%lu}!\n" + "Probably, you forgot the -fshort-wchar compiler option.\n", + (unsigned long) sizeof(PRUnichar), + (unsigned long) sizeof(wchar_t)); + return -1; + } + + nsresult rc; + + /* + * This is the standard XPCOM init procedure. + * What we do is just follow the required steps to get an instance + * of our main interface, which is IVirtualBox. + * + * Note that we scope all nsCOMPtr variables in order to have all XPCOM + * objects automatically released before we call NS_ShutdownXPCOM at the + * end. This is an XPCOM requirement. + */ + { + nsCOMPtr serviceManager; + rc = NS_InitXPCOM2(getter_AddRefs(serviceManager), nsnull, nsnull); + if (NS_FAILED(rc)) + { + RTPrintf("Error: XPCOM could not be initialized! rc=%Rhrc\n", rc); + return -1; + } + +#if 0 + /* + * Register our components. This step is only necessary if this executable + * implements XPCOM components itself which is not the case for this + * simple example. + */ + nsCOMPtr registrar = do_QueryInterface(serviceManager); + if (!registrar) + { + RTPrintf("Error: could not query nsIComponentRegistrar interface!\n"); + return -1; + } + registrar->AutoRegister(nsnull); +#endif + + /* + * Make sure the main event queue is created. This event queue is + * responsible for dispatching incoming XPCOM IPC messages. The main + * thread should run this event queue's loop during lengthy non-XPCOM + * operations to ensure messages from the VirtualBox server and other + * XPCOM IPC clients are processed. This use case doesn't perform such + * operations so it doesn't run the event loop. + */ + nsCOMPtr eventQ; + rc = NS_GetMainEventQ(getter_AddRefs (eventQ)); + if (NS_FAILED(rc)) + { + RTPrintf("Error: could not get main event queue! rc=%Rhrc\n", rc); + return -1; + } + + /* + * Now XPCOM is ready and we can start to do real work. + * IVirtualBox is the root interface of VirtualBox and will be + * retrieved from the XPCOM component manager. We use the + * XPCOM provided smart pointer nsCOMPtr for all objects because + * that's very convenient and removes the need deal with reference + * counting and freeing. + */ + nsCOMPtr manager; + rc = NS_GetComponentManager (getter_AddRefs (manager)); + if (NS_FAILED(rc)) + { + RTPrintf("Error: could not get component manager! rc=%Rhrc\n", rc); + return -1; + } + + nsCOMPtr virtualBox; + rc = manager->CreateInstanceByContractID (NS_VIRTUALBOX_CONTRACTID, + nsnull, + NS_GET_IID(IVirtualBox), + getter_AddRefs(virtualBox)); + if (NS_FAILED(rc)) + { + RTPrintf("Error, could not instantiate VirtualBox object! rc=%Rhrc\n", rc); + return -1; + } + RTPrintf("VirtualBox object created\n"); + + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + + + listVMs(virtualBox); + + createVM(virtualBox); + + + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + + /* this is enough to free the IVirtualBox instance -- smart pointers rule! */ + virtualBox = nsnull; + + /* + * Process events that might have queued up in the XPCOM event + * queue. If we don't process them, the server might hang. + */ + eventQ->ProcessPendingEvents(); + } + + /* + * Perform the standard XPCOM shutdown procedure. + */ + NS_ShutdownXPCOM(nsnull); + RTPrintf("Done!\n"); + return 0; +} + + +////////////////////////////////////////////////////////////////////////////////////////////////////// +//// Helpers +////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Helper function to convert an nsID into a human readable string + * + * @returns result string, allocated. Has to be freed using free() + * @param guid Pointer to nsID that will be converted. + */ +char *nsIDToString(nsID *guid) +{ + char *res = (char*)malloc(39); + + if (res != NULL) + { + RTStrPrintf(res, 39, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + guid->m0, (PRUint32)guid->m1, (PRUint32)guid->m2, + (PRUint32)guid->m3[0], (PRUint32)guid->m3[1], (PRUint32)guid->m3[2], + (PRUint32)guid->m3[3], (PRUint32)guid->m3[4], (PRUint32)guid->m3[5], + (PRUint32)guid->m3[6], (PRUint32)guid->m3[7]); + } + return res; +} + +/** + * Helper function to print XPCOM exception information set on the current + * thread after a failed XPCOM method call. This function will also print + * extended VirtualBox error info if it is available. + */ +void printErrorInfo() +{ + nsresult rc; + + nsCOMPtr es; + es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rc); + if (NS_SUCCEEDED(rc)) + { + nsCOMPtr em; + rc = es->GetCurrentExceptionManager (getter_AddRefs (em)); + if (NS_SUCCEEDED(rc)) + { + nsCOMPtr ex; + rc = em->GetCurrentException (getter_AddRefs (ex)); + if (NS_SUCCEEDED(rc) && ex) + { + nsCOMPtr info; + info = do_QueryInterface(ex, &rc); + if (NS_SUCCEEDED(rc) && info) + { + /* got extended error info */ + RTPrintf ("Extended error info (IVirtualBoxErrorInfo):\n"); + PRInt32 resultCode = NS_OK; + info->GetResultCode (&resultCode); + RTPrintf (" resultCode=%08X\n", resultCode); + nsXPIDLString component; + info->GetComponent (getter_Copies (component)); + RTPrintf (" component=%s\n", NS_ConvertUTF16toUTF8(component).get()); + nsXPIDLString text; + info->GetText (getter_Copies (text)); + RTPrintf (" text=%s\n", NS_ConvertUTF16toUTF8(text).get()); + } + else + { + /* got basic error info */ + RTPrintf ("Basic error info (nsIException):\n"); + nsresult resultCode = NS_OK; + ex->GetResult (&resultCode); + RTPrintf (" resultCode=%08X\n", resultCode); + nsXPIDLCString message; + ex->GetMessage (getter_Copies (message)); + RTPrintf (" message=%s\n", message.get()); + } + + /* reset the exception to NULL to indicate we've processed it */ + em->SetCurrentException (NULL); + + rc = NS_OK; + } + } + } +} -- cgit v1.2.1