// Unregister removes this from VirtualBox's list of registered machines. // The returned slice of Medium instances is intended to be passed to // DeleteConfig to get all the VM's files cleaned. // It returns an array of detached Medium instances and any error encountered. func (machine *Machine) Unregister(cleanupMode CleanupMode) ([]Medium, error) { var cmediaPtr **C.IMedium var mediaCount C.ULONG result := C.GoVboxMachineUnregister(machine.cmachine, C.PRUint32(cleanupMode), &cmediaPtr, &mediaCount) if C.GoVboxFAILED(result) != 0 || (cmediaPtr == nil && mediaCount != 0) { return nil, errors.New( fmt.Sprintf("Failed to unregister IMachine: %x", result)) } sliceHeader := reflect.SliceHeader{ Data: uintptr(unsafe.Pointer(cmediaPtr)), Len: int(mediaCount), Cap: int(mediaCount), } cmediaSlice := *(*[]*C.IMedium)(unsafe.Pointer(&sliceHeader)) var media = make([]Medium, mediaCount) for i := range cmediaSlice { media[i] = Medium{cmediaSlice[i]} } C.GoVboxArrayOutFree(unsafe.Pointer(cmediaPtr)) return media, nil }
// LockMachine obtains a lock on a VM, so it can be modified or started. // It returns any error encountered. func (session *Session) LockMachine(machine Machine, lockType LockType) error { result := C.GoVboxLockMachine(machine.cmachine, session.csession, C.PRUint32(lockType)) if C.GoVboxFAILED(result) != 0 { return errors.New(fmt.Sprintf("Failed to lock IMachine: %x", result)) } return nil }
// TakeScreenShotToArray takes a screenshot of the VM's display. // It returns a byte slice encoding the image as RGBA, and any error // encountered. func (display *Display) TakeScreenShotToArray(screenId uint, width uint, height uint) ([]byte, error) { var cdataPtr *C.PRUint8 var dataSize C.PRUint32 result := C.GoVboxDisplayTakeScreenShotToArray(display.cdisplay, C.PRUint32(screenId), C.PRUint32(width), C.PRUint32(height), &dataSize, &cdataPtr) if C.GoVboxFAILED(result) != 0 { return nil, errors.New( fmt.Sprintf("Failed to take IDisplay screenshot: %x", result)) } data := C.GoBytes(unsafe.Pointer(cdataPtr), C.int(dataSize)) C.GoVboxArrayOutFree(unsafe.Pointer(cdataPtr)) return data, nil }
// SetVramSize changes the machine's emulated mouse type. // It returns a number and any error encountered. func (machine *Machine) SetVramSize(vram uint) error { result := C.GoVboxSetMachineVRAMSize(machine.cmachine, C.PRUint32(vram)) if C.GoVboxFAILED(result) != 0 { return errors.New( fmt.Sprintf("Failed to set IMachine VRAM size: %x", result)) } return nil }
// SetBootMenuMode sets whether the BIOS logo fades out during boot. // It any error encountered. func (settings *BiosSettings) SetBootMenuMode(menuMode BootMenuMode) error { result := C.GoVboxSetBiosSettingsBootMenuMode(settings.csettings, C.PRUint32(menuMode)) if C.GoVboxFAILED(result) != 0 { return errors.New( fmt.Sprintf("Failed to set IBiosSettings boot menu mode: %x", result)) } return nil }
// TakeScreenShot takes a screenshot of the VM's display. // The slice passed in must be big enough to receive the image data, which is // RGBA (4 bytes per pixel). // It returns any error encountered. func (display *Display) TakeScreenShot(screenId uint, imageData []byte, width uint, height uint) ([]byte, error) { dataSize := int(width * height * 4) if dataSize > cap(imageData) { return nil, errors.New(fmt.Sprintf( "Insufficient slice capacity %d, screenshot needs at least %d", cap(imageData), dataSize)) } imageData = imageData[:dataSize] cdataPtr := (*C.PRUint8)(unsafe.Pointer(&imageData[0])) result := C.GoVboxDisplayTakeScreenShot(display.cdisplay, C.PRUint32(screenId), cdataPtr, C.PRUint32(width), C.PRUint32(height)) if C.GoVboxFAILED(result) != 0 { return nil, errors.New( fmt.Sprintf("Failed to take IDisplay fast screenshot: %x", result)) } return imageData, nil }
// SetPointingHidType changes the machine's emulated mouse type. // It returns a number and any error encountered. func (machine *Machine) SetPointingHidType( pointingHidType PointingHidType) error { result := C.GoVboxSetMachinePointingHIDType(machine.cmachine, C.PRUint32(pointingHidType)) if C.GoVboxFAILED(result) != 0 { return errors.New( fmt.Sprintf("Failed to set IMachine pointing HID type: %x", result)) } return nil }
// SetType changes the controller's type. // It returns a number and any error encountered. func (controller *StorageController) SetType( controllerType StorageControllerType) error { result := C.GoVboxSetStorageControllerType(controller.ccontroller, C.PRUint32(controllerType)) if C.GoVboxFAILED(result) != 0 { return errors.New( fmt.Sprintf("Failed to set IStorageController type: %x", result)) } return nil }
// CreateBaseStorage starts building a hard disk image. // It returns a Progress and any error encountered. func (medium *Medium) CreateBaseStorage( size uint64, variants []MediumVariant) (Progress, error) { var cvariants *C.PRUint32 if len(variants) > 0 { cvariantsSlice := make([]C.PRUint32, len(variants)) for i, variant := range variants { cvariantsSlice[i] = C.PRUint32(variant) } cvariants = &cvariantsSlice[0] } var progress Progress result := C.GoVboxMediumCreateBaseStorage(medium.cmedium, C.PRInt64(size), C.PRUint32(len(variants)), cvariants, &progress.cprogress) if C.GoVboxFAILED(result) != 0 || progress.cprogress == nil { return progress, errors.New( fmt.Sprintf("Failed to create IMedium storage: %x", result)) } return progress, nil }
// OpenMedium opens an image backing a VirtualBox storage medium. // It returns the newly opened Medium and any error encountered. func OpenMedium(location string, deviceType DeviceType, accessMode AccessMode, forceNewUuid bool) (Medium, error) { var medium Medium if err := Init(); err != nil { return medium, err } clocation := C.CString(location) cforceNewUuid := C.PRBool(0) if forceNewUuid { cforceNewUuid = C.PRBool(1) } result := C.GoVboxOpenMedium(cbox, clocation, C.PRUint32(deviceType), C.PRUint32(accessMode), cforceNewUuid, &medium.cmedium) C.free(unsafe.Pointer(clocation)) if C.GoVboxFAILED(result) != 0 || medium.cmedium == nil { return medium, errors.New( fmt.Sprintf("Failed to open IMedium: %x", result)) } return medium, nil }
// AttachDevice connects a Medium to this VM. // deviceSlot is 0 for IDE master and 1 for IDE slave. All other bus types use // deviceSlot 0. // It returns any error encountered. func (machine *Machine) AttachDevice(controllerName string, controllerPort int, deviceSlot int, deviceType DeviceType, medium Medium) error { cname := C.CString(controllerName) result := C.GoVboxMachineAttachDevice(machine.cmachine, cname, C.PRInt32(controllerPort), C.PRInt32(deviceSlot), C.PRUint32(deviceType), medium.cmedium) C.free(unsafe.Pointer(cname)) if C.GoVboxFAILED(result) != 0 { return errors.New( fmt.Sprintf("Failed to attach IMedium to IMachine: %x", result)) } return nil }
// PutScancodes posts keyboard scancodes to the guest OS event queue. // It returns any error encountered. func (keyboard *Keyboard) PutScancodes(scancodes []int) (uint, error) { scancodesCount := len(scancodes) cscancodes := make([]C.PRInt32, scancodesCount) for i, scancode := range scancodes { cscancodes[i] = C.PRInt32(scancode) } var ccodesStored C.PRUint32 result := C.GoVboxKeyboardPutScancodes(keyboard.ckeyboard, C.PRUint32(scancodesCount), &cscancodes[0], &ccodesStored) if C.GoVboxFAILED(result) != 0 { return uint(ccodesStored), errors.New( fmt.Sprintf("Failed to post IKeyboard scancodes: %x", result)) } return uint(ccodesStored), nil }
// AddUsbController attaches a storage controller to a VirtualBox VM. // It returns the created UsbController and any error encountered. func (machine *Machine) AddUsbController( name string, controllerType UsbControllerType) (UsbController, error) { var controller UsbController if err := Init(); err != nil { return controller, err } cname := C.CString(name) result := C.GoVboxMachineAddUsbController(machine.cmachine, cname, C.PRUint32(controllerType), &controller.ccontroller) C.free(unsafe.Pointer(cname)) if C.GoVboxFAILED(result) != 0 || controller.ccontroller == nil { return controller, errors.New(fmt.Sprintf( "Failed to add IUsbController: %x", result)) } return controller, nil }
// GetScreenResolution reads the VM display's resolution. // It returns any error encountered. func (display *Display) GetScreenResolution(screenId uint, resolution *Resolution) error { var cwidth, cheight, cbitsPerPixel C.PRUint32 var cxOrigin, cyOrigin C.PRInt32 result := C.GoVboxDisplayGetScreenResolution(display.cdisplay, C.PRUint32(screenId), &cwidth, &cheight, &cbitsPerPixel, &cxOrigin, &cyOrigin) if C.GoVboxFAILED(result) != 0 { return errors.New( fmt.Sprintf("Failed to get IDisplay resolution: %x", result)) } resolution.Width = uint(cwidth) resolution.Height = uint(cheight) resolution.BitsPerPixel = uint(cbitsPerPixel) resolution.XOrigin = int(cxOrigin) resolution.YOrigin = int(cyOrigin) return nil }
// DeleteConfig removes a VM's config file, and can remove its disk images. // The Medium array is intended to be obtained from a previous Unregister call. // It returns a Progress instance and any error encountered. func (machine *Machine) DeleteConfig(media []Medium) (Progress, error) { var cmediaSlice []*C.IMedium var cmedia **C.IMedium if len(media) > 0 { cmediaSlice = make([]*C.IMedium, len(media)) for i, medium := range media { cmediaSlice[i] = medium.cmedium } cmedia = &cmediaSlice[0] } var progress Progress result := C.GoVboxMachineDeleteConfig(machine.cmachine, C.PRUint32(len(media)), cmedia, &progress.cprogress) if C.GoVboxFAILED(result) != 0 || progress.cprogress == nil { return progress, errors.New( fmt.Sprintf("Failed to delete IMachine config: %x", result)) } return progress, nil }