Controlling Mouse Movement of the VM

Discussion about using the VirtualBox API, Tutorials, Samples.
HenryHux
Posts: 8
Joined: 3. Jun 2013, 12:34

Controlling Mouse Movement of the VM

Post by HenryHux »

Hey,

I'd like to send messages to the VM to move it's mouse so that the mouse of the host stays unaffected.
Is there any way to achieve this using c or c++?
I'd prefer using the VirtualBox Manager (if it has its own API) since I had some trouble using the VM API and I only need this one function.

Thanks!
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Controlling Mouse Movement of the VM

Post by noteirak »

There are two methods that you can use in the IMouse internface obtained from IConsole::getMouse() :
putMouseEvent
putMouseEventAbsolute

Never used them myself so cannot tell you if they work, but give it a try.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
HenryHux
Posts: 8
Joined: 3. Jun 2013, 12:34

Re: Controlling Mouse Movement of the VM

Post by HenryHux »

But therefore I will need to build my own VM Manager right?
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Controlling Mouse Movement of the VM

Post by noteirak »

What do you mean by VM Manager exactly? the GUI that directly controls the VM? AFAIK no you don't need to, only to connect via the API like you would normally do.
Do you already have some code for this?
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
HenryHux
Posts: 8
Joined: 3. Jun 2013, 12:34

Re: Controlling Mouse Movement of the VM

Post by HenryHux »

Yes, I already have some code, taken from the example provided with the sdk.
However, this doesn't work for me since I am getting an error code which I cannot find a description to.
Executing this example:

Code: Select all

{
    HRESULT rc;
    IVirtualBox *virtualBox;

	/* Initialize the COM subsystem. */
    CoInitialize(NULL);
    do
    {
        /* Instantiate the VirtualBox root object. */
        rc = CoCreateInstance(CLSID_VirtualBox,       /* the VirtualBox base object */
                              NULL,                   /* no aggregation */
                              CLSCTX_LOCAL_SERVER,    /* the object lives in a server process on this machine */
                              IID_IVirtualBox,        /* IID of the interface */
                              (void**)&virtualBox);

        if (!SUCCEEDED(rc))
        {
            printf("Error creating VirtualBox instance! rc = 0x%x\n", rc);
            break;
        }
        /* Release the VirtualBox object. */
        virtualBox->Release();

    } while (0);

    CoUninitialize();
	getchar();
    return 0;
}
throws up this error : "Error creating VirtualBox instance! rc = 0x80004002".
Unfortunatly, there is no documentation about it..
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Controlling Mouse Movement of the VM

Post by noteirak »

Where is this example located exactly, in the SDK?
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
HenryHux
Posts: 8
Joined: 3. Jun 2013, 12:34

Re: Controlling Mouse Movement of the VM

Post by HenryHux »

Code: Select all

virtualbox.or g/wiki/Downloads
-> SDK -> ..\sdk\bindings\mscom\samples
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Controlling Mouse Movement of the VM

Post by noteirak »

I found that sample code quite odd, since it doesn't really match other languages sample, until I read the following :

Code: Select all

 * PURPOSE OF THIS SAMPLE PROGRAM
 * ------------------------------
 *
 * This sample program is intended to demonstrate the minimal code necessary
 * to use VirtualBox COM API for learning puroses only. The program uses pure
 * Win32 API 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 COM 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.
And as a "solution" :

Code: Select all

 * 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.
I strongly suggest you have a look in the source code directly.
I personally have never dealt with the mscom so my knowledge stops here.

You can also head towards the dev mailing list.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
HenryHux
Posts: 8
Joined: 3. Jun 2013, 12:34

Re: Controlling Mouse Movement of the VM

Post by HenryHux »

Thanks!
Today, I took another try and got the example (partly) working.
Seems I was using outdated files.
Now, the API lists my installed virtual machines correctly and doesn't throw any errors.

However, I have some trouble starting the VM.
Starting the application without admin rights results in a successfull creation of the the VirtualBox instance but fails creating the session instance with Error code : 0x80040154. (-> most likely due to missing admin rights)
Starting the application with admin rights throws an error (0x8008005) right when creating the VirtualBox Instance (means doesn't get as far as without admin rights ; till then, application freezes about 1min).

I guess since I can retrieve some information like VM-Names, the application is working fine but the problem is somewhere else.
Do you have any idea?

Thanks

Code: Select all

	IVirtualBox *virtualBox;
    rc = CoCreateInstance(CLSID_VirtualBox,                                     //fails with admin rights, but not without
						  NULL,
						  CLSCTX_LOCAL_SERVER,
						  IID_IVirtualBox,
						  (void**)&virtualBox);
	
    if (!SUCCEEDED(rc))
        printf("Error creating VirtualBox instance! rc = 0x%x", rc);


	ISession *session = NULL;
    rc = CoCreateInstance(CLSID_Session,                                 //fails with both
						  NULL,       
						  CLSCTX_INPROC_SERVER,
						  IID_ISession,  
						  (void**)&session);

    if (!SUCCEEDED(rc))
        printf("Error creating Session instance! rc = 0x%x", rc);
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Controlling Mouse Movement of the VM

Post by noteirak »

First of all, you must run your code under the user that has the VMs. If that user is not Administrator, don't :)
Please show me the code you use to start the VM. Most likely, you're just missing something.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
HenryHux
Posts: 8
Joined: 3. Jun 2013, 12:34

Re: Controlling Mouse Movement of the VM

Post by HenryHux »

Okay, I've taken the function out of the example.
Here you go:

Code: Select all

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(NULL);

	IVirtualBox *virtualBox;
    HRESULT rc = CoCreateInstance(CLSID_VirtualBox,
						  NULL,
						  CLSCTX_LOCAL_SERVER,
						  IID_IVirtualBox,
						  (void**)&virtualBox);
	
    if (!SUCCEEDED(rc))
        printf("Error creating VirtualBox instance! rc = 0x%x\n", rc);
	else
		listVMs(virtualBox);

	testStartVM(virtualBox, L"TestMachine");

	virtualBox->Release();

	CoUninitialize();

	getchar();
	return 0;
}

Code: Select all

int testStartVM(IVirtualBox *virtualBox, OLECHAR *MachineName)
{
    HRESULT rc;

    /* Try to start a VM*/
    IMachine *machine = NULL;
    BSTR machineName = SysAllocString(MachineName);

    rc = virtualBox->FindMachine(machineName, &machine);

    if (FAILED(rc))
    {
        IErrorInfo *errorInfo;

        rc = GetErrorInfo(0, &errorInfo);

        if (FAILED(rc))
            printf("Error getting error info! rc = 0x%x\n", rc);
        else
        {
            BSTR errorDescription = NULL;

            rc = errorInfo->GetDescription(&errorDescription);

            if (FAILED(rc) || !errorDescription)
                printf("Error getting error description! rc = 0x%x\n", rc);
            else
            {
                printf("Successfully retrieved error description: %S\n", errorDescription);

                SysFreeString(errorDescription);
            }

            SAFE_RELEASE(errorInfo);
        }
    }
    else
    {
        ISession *session = NULL;
        IConsole *console = NULL;
        IProgress *progress = NULL;
        BSTR sessiontype = SysAllocString(L"gui");
        BSTR guid;

        do
        {
            rc = machine->get_Id(&guid); /* Get the GUID of the machine. */
            if (!SUCCEEDED(rc))
            {
                printf("Error retrieving machine ID! rc = 0x%x\n", rc);
                break;
            }
            /* Create the session object. */
            rc = CoCreateInstance(CLSID_Session,        //the VirtualBox base object 
                                  NULL,                 //no aggregation 
                                  CLSCTX_INPROC_SERVER, //the object lives in a server process on this machine 
                                  IID_ISession,         //IID of the interface 
                                  (void**)&session);
            if (!SUCCEEDED(rc))
            {
                printf("Error creating Session instance! rc = 0x%x\n", rc);
                break;
            }

            /* Start a VM session using the delivered VBox GUI. */
            rc = machine->LaunchVMProcess(session, sessiontype,
                                          NULL, &progress);
            if (!SUCCEEDED(rc))
            {
                printf("Could not open remote session! rc = 0x%x\n", rc);
                break;
            }

            /* Wait until VM is running. */
            printf ("Starting VM, please wait ...\n");
            rc = progress->WaitForCompletion (-1);

            /* Get console object. */
            session->get_Console(&console);

            /* Bring console window to front. */
            machine->ShowConsoleWindow(0);

            printf ("Press enter to power off VM and close the session...\n");
            getchar();

            /* Power down the machine. */
            rc = console->PowerDown(&progress);

            /* Wait until VM is powered down. */
            printf ("Powering off VM, please wait ...\n");
            rc = progress->WaitForCompletion (-1);

            /* Close the session. */
            rc = session->UnlockMachine();

        } while (0);

        SAFE_RELEASE(console);
        SAFE_RELEASE(progress);
        SAFE_RELEASE(session);
        SysFreeString(guid);
        SysFreeString(sessiontype);
        SAFE_RELEASE(machine);
    }

    SysFreeString(machineName);

    return 0;
}
Still getting the "Error creating Session instance! rc = 0x80040154" aka NS_ERROR_FACTORY_NOT_REGISTERED
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Controlling Mouse Movement of the VM

Post by noteirak »

You should stop using that code and go with the Glue code, just like mentionned into the sample file. There is no guarantee that code is still working and most likely is not.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
HenryHux
Posts: 8
Joined: 3. Jun 2013, 12:34

Re: Controlling Mouse Movement of the VM

Post by HenryHux »

Well, it is used by other (working) services like VBoxVMService (exactly the same method) and is also used in the latest VirtualBox, so it must be the right approach.
However, GetLastError() return
ERROR_SXS_KEY_NOT_FOUND
14007 (0x36B7)
The requested lookup key was not found in any active activation context.
Maybe this helps?
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Controlling Mouse Movement of the VM

Post by noteirak »

Well sure, I just have no idea how to fix it tho :D
Maybe you should go on the dev mailing list directly. The MSCOM code seems rather different from "regular" code, and I have no way to test it myself. Better to seek the best advice directly.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
HenryHux
Posts: 8
Joined: 3. Jun 2013, 12:34

Re: Controlling Mouse Movement of the VM

Post by HenryHux »

Okay, here we go.
MSCOM works absolutely fine, just not on my OS :D
I always tried executing the application on my laptop and computer, both having installed Win8 x64.
I now tried it on an old netbook running Win7 x86. What happens? Vm is starting up, no errors, just everything as it should be.
Now, I am trying to figure out what the problem could be.
Wrong permissions? Wrong core architecture (conflict between x64 and x86)? Different environmental Vars?
There are just a lot of things I will probably never figure out.
In hindsight of the windows error 14007 - ERROR_SXS_KEY_NOT_FOUND, I would guess some paths are fcked up.
However, got no clue how to solve it.
Do you have any ideas?

Thanks! :)
Post Reply