LockMachine(..) not working

Discussion about using the VirtualBox API, Tutorials, Samples.
Post Reply
MLKKK
Posts: 6
Joined: 10. Jan 2017, 18:47

LockMachine(..) not working

Post by MLKKK »

down vote
favorite
I'm trying to move the mouse inside a VirtualBox Guest programmatically, but I can't get the steps right to actually use the mouse move function. Using C++. Building with nmake.

Here's the code. The virtual machine is running while I try this. If i run the program while it's virtual machine is shut down, I get a lock successfully but then the call console->getMouse causes a crash. Everything works fine, no errors until getConsole, where I find out that the session I give it is unlocked.

Code: Select all

int main()
{

HRESULT rc;
IVirtualBox *virtualBox;

do
{
    /* Initialize the COM subsystem. */
    CoInitialize(NULL);


    /* Instantiate the VirtualBox root object. */
    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);
        break;
    }

    //listVMs(virtualBox);

    //testErrorInfo(virtualBox);

    ISession *session = NULL;
    /* 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;
    }
    printf("Session instance created.\n");

    IMachine *machine = NULL;
    rc = virtualBox->FindMachine(SysAllocString(L"OVM1"), &machine);
    if (!SUCCEEDED(rc))
    {
        printf("Error vm not found\n");
        break;
    }
    printf("VM found.\n");
    machine->LockMachine (session, LockType_Shared);

    SessionType type;
    session->get_Type(&type);
    printf("typ: %d\n", type);

    BSTR name;
    machine->get_Name(&name);
    printf("nam: %S\n", name);
    /* Get console object. */
    IConsole *console = NULL;
    IMouse *mouse = NULL;
    rc = session->get_Console(&console);
    if (!SUCCEEDED(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);
    }

        printf("Error opening console\n");
        break;
    }
    printf("Console opened.\n");
    console->get_Mouse(&mouse);
    lasterror();
    BOOL supported=false;

    mouse->get_AbsoluteSupported(&supported);
    if(supported)
    {
        printf("Absolute Supported\n");
    }
    rc = mouse->PutMouseEventAbsolute(100,100,0,0,0);
    if (rc==VBOX_E_IPRT_ERROR)
    {
        printf("Error sending mouse event\n");
        break;
    }
    rc = mouse->PutMouseEvent(10,10,0,0,0);
    /* Enable the following line to get a VM started. */
    //testStartVM(virtualBox);

    /* Release the VirtualBox object. */
    session->UnlockMachine();
    virtualBox->Release();

} while (0);
Sleep(200000);
CoUninitialize();
return 0;
}
I inserted this error code retrieval after the LockMachine call, which also makes the program crash:

Code: Select all

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);
        }

Any help is welcome, thank you.
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: LockMachine(..) not working

Post by noteirak »

The ISession object is created using the VirtualBox API, not by creating the object yourself (if I read your code correctly)
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
MLKKK
Posts: 6
Joined: 10. Jan 2017, 18:47

Re: LockMachine(..) not working

Post by MLKKK »

It's created with CoCreateInstance from the COM. The entire code I got off this forum actually. My only additions are error checks.

Are you saying I should initialize it like so:

Code: Select all

       VirtualBoxManager mgr = VirtualBoxManager.createInstance(null);
        ISession session = mgr.getSessionObject();
I just tried it and doesn't work. It says VirtualBoxManager is undefined. From the documentation it seems I need the SDK installation paths in order to get VirtuaLBoxManager, but it seems I don't have any paths, and I can't run vboxapisetup.py; when I try python just says: no commands supplied.
klaus
Oracle Corporation
Posts: 1133
Joined: 10. May 2007, 14:57

Re: LockMachine(..) not working

Post by klaus »

What's unclear to me is if the VM you want to remote control is actually running already... because if it's not then your code will get a NULL pointer for console and would crash exactly in the place you're looking at - use the debugger, Luke :D

It should quickly tell you what's going on. As usual there's plenty of sample code for pretty much any API function use in VBoxManage (yes, I know, using the glue code which makes API coding a lot less tedious but which unfortunately hasn't made it yet to the SDK)...
MLKKK
Posts: 6
Joined: 10. Jan 2017, 18:47

Re: LockMachine(..) not working

Post by MLKKK »

Yea, the machine is running. I also mentioned that I tried running my program while machine is shut down, and I do get a lock successfully, but it crashes witt the console stuff.
I consulted code samples, that's where I got my code, but it isn't working..
klaus
Oracle Corporation
Posts: 1133
Joined: 10. May 2007, 14:57

Re: LockMachine(..) not working

Post by klaus »

You're always switching so fast between the working and non-working case that it's not really clear what exactly your issue is.

I'm now assuming that there's absolutely no issue when the VM is running, but you see a crash when blindly using the console pointer (or when inserting your error retrieval code snippet after the LockMachine call, which is buggy and incorrectly checks the return value of GetErrorInfo(), again running into a NULL pointer dereference, ultimately simply because there was no error in the LockMachine call).

If you complain about trouble when the VM is not running then you're complaining about expected and documented behavior (see e.g. the console attribute docs on https://www.virtualbox.org/sdkref/inter ... ssion.html). The locking of the VM you use will always succeed (why should a shared lock attempt fail when no one else is around holding any lock for that VM?). If there's no running VM process for the machine you want there's also no associated console object, which explains why you get a NULL object reference. I don't see any logical flaws on the API side, especially I see no need to signal an error when getting the console attribute.

Yes, the behavior of the API has changed in this area, so it is possible that the sample you got from the forum was correct at the time it was posted. In ancient days there was a dummy console object created, but as this is very expensive and caused library dependency problems without any pros (besides allowing people to be lazy with NULL object reference checks) it was abandoned years ago, following a more clean separation of what lives where. Only VM processes have an associated console, and if there's no such process currently running you get NULL.
Post Reply