コード例 #1
0
ファイル: vboxgo.go プロジェクト: milosradovanovic/vboxgo
func (vb *VirtualBox) Init() error {
	if C.VBoxCGlueInit() != 0 {
		message := fmt.Sprintf("VBoxCGlueInit failed: %v", C.g_szVBoxErrMsg)
		log.Println(message)
		return errors.New(message)
	}

	//unsigned ver = g_pVBoxFuncs->pfnGetVersion();
	//printf("VirtualBox version: %u.%u.%u\n", ver / 1000000, ver / 1000 % 1000, ver % 1000);
	//ver = g_pVBoxFuncs->pfnGetAPIVersion();
	//printf("VirtualBox API version: %u.%u\n", ver / 1000, ver % 1000);

	C.ClientInitialize(&vb.vboxclient)
	if vb.vboxclient == nil {
		message := fmt.Sprintf("Could not get vboxclient reference")
		log.Println(message)
		return errors.New(message)
	}

	var rc C.HRESULT = C.GetVirtualBox(vb.vboxclient, &vb.vbox)
	if C.MY_FAILED(rc) != 0 || vb.vbox == nil {
		message := fmt.Sprintf("Could not get vbox reference")
		log.Println(message)
		return errors.New(message)
	}

	rc = C.GetSession(vb.vboxclient, &vb.session)
	if C.MY_FAILED(rc) != 0 || vb.session == nil {
		message := fmt.Sprintf("Could not get session reference")
		log.Println(message)
		return errors.New(message)
	}

	return nil
}
コード例 #2
0
ファイル: vboxgo.go プロジェクト: milosradovanovic/vboxgo
func (vm *VirtualMachine) GetScreenshot() (*image.NRGBA, error) {
	if !vm.locked {
		message := fmt.Sprintf("Machine not locked, can't take screenshot")
		log.Println(message)
		return nil, errors.New(message)
	}

	width := C.uint(0)
	height := C.uint(0)
	bitsPerPixel := C.uint(0)

	//TODO: is vm.Display threadsafe?
	var rc C.HRESULT = C.GetScreenResolution(vm.Display, &width, &height, &bitsPerPixel)
	if C.MY_FAILED(rc) != 0 {
		message := fmt.Sprintf("Failed to get screen resolution")
		log.Println(message)
		return nil, errors.New(message)
	}

	//var imageData [int(width)*(height)*4]char
	var imageDataSize C.PRUint32
	var imageData *C.PRUint8
	defer C.free(unsafe.Pointer(imageData))

	rc = C.TakeScreenShotPNGToArray(vm.Display, width, height, &imageDataSize, &imageData)
	if C.MY_FAILED(rc) != 0 {
		message := fmt.Sprintf("Failed to get screen shot data")
		log.Println(message)
		return nil, errors.New(message)
	}

	// convert data to a go byte array
	dataSize := int(imageDataSize)
	dataBytes := C.GoBytes(unsafe.Pointer(imageData), C.int(dataSize))

	reader := bytes.NewReader(dataBytes)
	imgUnknown, err := png.Decode(reader) //this guy is probably RGBA
	if err != nil {
		message := fmt.Sprintf("Failed to decode image from png raw data", err)
		log.Println(message)
		return nil, err
	}

	// copy the image into NRGBA format. This is wasteful (TODO?)
	b := imgUnknown.Bounds()
	imgNRGBA := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
	draw.Draw(imgNRGBA, imgNRGBA.Bounds(), imgUnknown, b.Min, draw.Src)

	return imgNRGBA, nil
}
コード例 #3
0
ファイル: vboxgo.go プロジェクト: milosradovanovic/vboxgo
// I guess this one expects the vm to be active already, the other possibility would be "LaunchVMProcess"
func (vm *VirtualMachine) LockMachine() error {
	var rc C.HRESULT = C.LockMachine(vm.Machine, vm.Session)
	if C.MY_FAILED(rc) != 0 {
		vm.locked = false
		message := fmt.Sprintf("Could not lock machine")
		log.Println(message)
		return errors.New(message)
	}
	vm.locked = true

	rc = C.GetConsole(vm.Session, &vm.Console)
	if C.MY_FAILED(rc) != 0 || vm.Console == nil {
		vm.UnlockMachine()
		message := fmt.Sprintf("Could not get console reference")
		log.Println(message)
		return errors.New(message)
	}

	rc = C.GetMouse(vm.Console, &vm.Mouse)
	if C.MY_FAILED(rc) != 0 || vm.Mouse == nil {
		vm.UnlockMachine()
		message := fmt.Sprintf("Could not get mouse reference")
		log.Println(message)
		return errors.New(message)
	}

	rc = C.GetKeyboard(vm.Console, &vm.Keyboard)
	if C.MY_FAILED(rc) != 0 || vm.Keyboard == nil {
		vm.UnlockMachine()
		message := fmt.Sprintf("Could not get keyboard reference")
		log.Println(message)
		return errors.New(message)
	}

	rc = C.GetDisplay(vm.Console, &vm.Display)
	if C.MY_FAILED(rc) != 0 || vm.Display == nil {
		vm.UnlockMachine()
		message := fmt.Sprintf("Could not get display reference")
		log.Println(message)
		return errors.New(message)
	}

	return nil
}
コード例 #4
0
ファイル: vboxgo.go プロジェクト: milosradovanovic/vboxgo
func (vm *VirtualMachine) UnlockMachine() error {
	var rc C.HRESULT = C.UnlockMachine(vm.Session)

	if C.MY_FAILED(rc) != 0 {
		message := fmt.Sprintf("Could not unlock machine")
		log.Println(message)
		return errors.New(message)
	}

	vm.locked = false
	return nil
}
コード例 #5
0
ファイル: vboxgo.go プロジェクト: milosradovanovic/vboxgo
//state should be one of MOUSE_EVENT_...
func (vm *VirtualMachine) MouseEvent(x, y, state int) error {
	if !vm.locked {
		message := fmt.Sprintf("Machine not locked, can't perform mouse down")
		log.Println(message)
		return errors.New(message)
	}

	var rc C.HRESULT = C.MouseClickEvent(vm.Mouse, C.int(x), C.int(y), C.int(state))
	if C.MY_FAILED(rc) != 0 {
		message := fmt.Sprintf("Failed to perform mouse down")
		log.Println(message)
		return errors.New(message)
	}

	return nil
}
コード例 #6
0
ファイル: vboxgo.go プロジェクト: milosradovanovic/vboxgo
// TODO: name is actually nameOrId
func (vb *VirtualBox) ConnectToMachine(name string) (*VirtualMachine, error) {
	var machine *C.IMachine

	cs := C.CString(name)
	defer C.free(unsafe.Pointer(cs))
	var rc C.HRESULT = C.FindMachine(vb.vbox, cs, &machine)
	if C.MY_FAILED(rc) != 0 || machine == nil {
		if machine != nil {
			defer C.free(unsafe.Pointer(machine))
		}

		message := fmt.Sprintf("Could not get machine reference")
		log.Println(message)
		return nil, errors.New(message)
	}

	vm := new(VirtualMachine)
	vm.Machine = machine
	vm.Name = name
	vm.Session = vb.session
	vm.locked = false

	return vm, nil
}