Code: Select all
#include <wtypes.h>
#include "VirtualBox.h"
#include "VBApi.h"
// GLOBAL VARIABLES
IVirtualBoxClient *CLIENT = NULL;
IDisplay *DISPLAY = NULL;
SAFEARRAY *BUFFER = NULL;
int PREVIOUS_INDEX = 0;
// Find running virtual machine. It's name coded by index.
// Returns pointer to display interface, NULL if something goes wrong.
IDisplay* findVM (int index) {
HRESULT rc;
if (!CLIENT) {
rc = CoCreateInstance(CLSID_VirtualBoxClient, NULL, CLSCTX_INPROC_SERVER,IID_IVirtualBoxClient, (void**)&CLIENT);
if FAILED(rc) return NULL;
}
IVirtualBox* box;
rc = CLIENT->get_VirtualBox(&box);
if FAILED(rc) return NULL;
ISession* session;
rc = CLIENT->get_Session(&session);
if FAILED(rc) return NULL;
IMachine *machine = NULL;
BSTR name;
// The code breaks all the ideological doctrine of programming, but it dosn't matter.
// If you have a idea, please implement it without explanations, because I'm ignoramus in C++ (the DLL will be used from the exotic scripting language).
switch (index) {
case 1: name = SysAllocString(L"Win2000"); break;
case 2: name = SysAllocString(L"WinXP"); break;
case 3: name = SysAllocString(L"WinVista"); break;
case 4: name = SysAllocString(L"Win7"); break;
default: return NULL;
}
rc = box->FindMachine(name, &machine);
SysFreeString(name);
if FAILED(rc) return NULL;
MachineState state = MachineState_Null;
rc = machine->get_State(&state);
if (FAILED(rc) || (state != MachineState_Running)) return NULL;
rc = machine->LockMachine(session, LockType_Shared);
if FAILED(rc) return NULL;
IConsole* console;
rc = session->get_Console(&console);
if FAILED(rc) return NULL;
IDisplay *display;
rc = console->get_Display(&display);
if FAILED(rc) return NULL;
rc = session->UnlockMachine();
if FAILED(rc) return NULL;
return display;
}
// Returns a pointer to the screenshot.
SAFEARRAY* __stdcall takeScreen(int index) {
if (index <= 0) return NULL;
if (index != PREVIOUS_INDEX) {
DISPLAY = findVM(index);
PREVIOUS_INDEX = 0; // if findVM fails, then it to be repeated at the next call of takeScreen.
if (!DISPLAY) return NULL;
PREVIOUS_INDEX = index;
}
if (BUFFER) {
SafeArrayDestroy(BUFFER);
BUFFER = NULL;
}
HRESULT rc = DISPLAY->TakeScreenShotToArray(0, 1024, 768, &BUFFER);
if FAILED(rc) return NULL;
return BUFFER;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,LPVOID lpvReserved) {
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
CoInitialize(NULL);
break;
case DLL_PROCESS_DETACH:
if (CLIENT) {
CLIENT->Release();
CLIENT = NULL;
}
if (BUFFER) {
SafeArrayDestroy(BUFFER);
BUFFER = NULL;
}
}
return TRUE;
}