vboxapi.py revision 2561352ae77d8f2f825526a6cbafa34b45f16972
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync#
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# Copyright (C) 2009 Sun Microsystems, Inc.
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync#
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# This file is part of VirtualBox Open Source Edition (OSE), as
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# available from http://www.virtualbox.org. This file is free software;
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# you can redistribute it and/or modify it under the terms of the GNU
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# General Public License (GPL) as published by the Free Software
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# Foundation, in version 2 as it comes in the "COPYING" file of the
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync#
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# Clara, CA 95054 USA or visit http://www.sun.com if you need
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync# additional information or have any questions.
5f40efb5cd27c6ff21ca70bf3271564e7e79e3a4vboxsync#
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncimport sys,os
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncimport traceback
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncVboxBinDir = os.environ.get("VBOX_PROGRAM_PATH", None)
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncVboxSdkDir = os.environ.get("VBOX_SDK_PATH", None)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncif VboxBinDir is None:
2561352ae77d8f2f825526a6cbafa34b45f16972vboxsync # Will be set by the installer
2561352ae77d8f2f825526a6cbafa34b45f16972vboxsync VboxBinDir = "%VBOX_INSTALL_PATH%"
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncif VboxSdkDir is None:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync VboxSdkDir = VboxBinDir+"/sdk"
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncos.environ["VBOX_PROGRAM_PATH"] = VboxBinDir
2561352ae77d8f2f825526a6cbafa34b45f16972vboxsync#os.environ["VBOX_SDK_PATH"] = VboxSdkDir
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncsys.path.append(VboxBinDir)
2561352ae77d8f2f825526a6cbafa34b45f16972vboxsync#sys.path.append(VboxSdkDir+"/bindings/glue/python")
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
c65e2fedaf400b449a85ae6db7b84858f2613708vboxsyncfrom VirtualBox_constants import VirtualBoxReflectionInfo
c65e2fedaf400b449a85ae6db7b84858f2613708vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncclass PlatformMSCOM:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync class ConstantFake:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def __init__(self, parent, name):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.__dict__['_parent'] = parent
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.__dict__['_name'] = name
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.__dict__['_consts'] = {}
08122b11035de1e54ce1e665dff7260fc548db72vboxsync try:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.__dict__['_depth']=parent.__dict__['_depth']+1
08122b11035de1e54ce1e665dff7260fc548db72vboxsync except:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.__dict__['_depth']=0
08122b11035de1e54ce1e665dff7260fc548db72vboxsync if self.__dict__['_depth'] > 4:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync raise AttributeError
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync def __getattr__(self, attr):
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync import win32com
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync from win32com.client import constants
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync if attr.startswith("__"):
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync raise AttributeError
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync consts = self.__dict__['_consts']
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync fake = consts.get(attr, None)
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync if fake != None:
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync return fake
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync try:
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync name = self.__dict__['_name']
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync parent = self.__dict__['_parent']
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync while parent != None:
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync if parent._name is not None:
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync name = parent._name+'_'+name
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync parent = parent._parent
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync if name is not None:
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync name += "_" + attr
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync else:
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync name = attr
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync print "ask",name
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync return win32com.client.constants.__getattr__(name)
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync except AttributeError,e:
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync fake = PlatformMSCOM.ConstantFake(self, attr)
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync consts[attr] = fake
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync return fake
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync class InterfacesWrapper:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def __init__(self):
da570ef57fe454ae2d9d5d88a7bfea214723dbb1vboxsync self.__dict__['_rootFake'] = PlatformMSCOM.ConstantFake(None, None)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def __getattr__(self, a):
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync import win32com
7baa1c3bb51b48e79eee63a69e341442e342a18evboxsync from win32com.client import constants
08122b11035de1e54ce1e665dff7260fc548db72vboxsync if a.startswith("__"):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync raise AttributeError
08122b11035de1e54ce1e665dff7260fc548db72vboxsync try:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return win32com.client.constants.__getattr__(a)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync except AttributeError,e:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return self.__dict__['_rootFake'].__getattr__(a)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def __init__(self, params):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync sys.path.append(VboxSdkDir+'/bindings/mscom/python/')
08122b11035de1e54ce1e665dff7260fc548db72vboxsync from win32com import universal
08122b11035de1e54ce1e665dff7260fc548db72vboxsync from win32com.client import gencache, DispatchWithEvents, Dispatch
08122b11035de1e54ce1e665dff7260fc548db72vboxsync from win32com.client import constants, getevents
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import win32com.server.register
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import win32com
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import pythoncom
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import win32api
da570ef57fe454ae2d9d5d88a7bfea214723dbb1vboxsync self.constants = PlatformMSCOM.InterfacesWrapper()
2ea0ec406117609d51bd5ac51cbb3d4f0de9a16dvboxsync #win32com.client.gencache.EnsureDispatch('VirtualBox.Session')
2ea0ec406117609d51bd5ac51cbb3d4f0de9a16dvboxsync #win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox')
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync def getSessionObject(self, vbox):
da570ef57fe454ae2d9d5d88a7bfea214723dbb1vboxsync import win32com
08122b11035de1e54ce1e665dff7260fc548db72vboxsync from win32com.client import Dispatch
2ea0ec406117609d51bd5ac51cbb3d4f0de9a16dvboxsync return win32com.client.Dispatch("VirtualBox.Session")
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getVirtualBox(self):
da570ef57fe454ae2d9d5d88a7bfea214723dbb1vboxsync import win32com
08122b11035de1e54ce1e665dff7260fc548db72vboxsync from win32com.client import Dispatch
2ea0ec406117609d51bd5ac51cbb3d4f0de9a16dvboxsync return win32com.client.Dispatch("VirtualBox.VirtualBox")
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getConstants(self):
da570ef57fe454ae2d9d5d88a7bfea214723dbb1vboxsync return self.constants
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getType(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return 'MSCOM'
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getRemote(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return False
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getArray(self, obj, field):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return obj.__getattr__(field)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync def initPerThread(self):
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync import pythoncom
1d27f9d208503988168cd9a8a902a0f48cf52a12vboxsync pythoncom.CoInitializeEx(0)
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync def deinitPerThread(self):
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync import pythoncom
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync pythoncom.CoUninitialize()
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncclass PlatformXPCOM:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def __init__(self, params):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync sys.path.append(VboxSdkDir+'/bindings/xpcom/python/')
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import xpcom.vboxxpcom
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import xpcom
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import xpcom.components
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync def getSessionObject(self, vbox):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import xpcom.components
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return xpcom.components.classes["@virtualbox.org/Session;1"].createInstance()
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getVirtualBox(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import xpcom.components
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return xpcom.components.classes["@virtualbox.org/VirtualBox;1"].createInstance()
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getConstants(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import xpcom.components
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return xpcom.components.interfaces
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getType(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return 'XPCOM'
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getRemote(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return False
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getArray(self, obj, field):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return obj.__getattr__('get'+field.capitalize())()
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync def initPerThread(self):
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync pass
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync def deinitPerThread(self):
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync pass
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncclass PlatformWEBSERVICE:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def __init__(self, params):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync sys.path.append(VboxSdkDir+'/bindings/webservice/python/lib')
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import VirtualBox_services
08122b11035de1e54ce1e665dff7260fc548db72vboxsync import VirtualBox_wrappers
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync from VirtualBox_wrappers import IWebsessionManager2
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync if params is not None:
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync self.user = params.get("user", "")
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync self.password = params.get("password", "")
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync self.url = params.get("url", "")
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync else:
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync self.user = ""
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync self.password = ""
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync self.url = None
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync self.wsmgr = IWebsessionManager2(self.url)
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync def getSessionObject(self, vbox):
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync return self.wsmgr.getSessionObject(vbox)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getVirtualBox(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return self.wsmgr.logon(self.user, self.password)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getConstants(self):
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync return None
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getType(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return 'WEBSERVICE'
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getRemote(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return True
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getArray(self, obj, field):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return obj.__getattr__(field)
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync def initPerThread(self):
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync pass
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync def deinitPerThread(self):
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync pass
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncclass SessionManager:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def __init__(self, mgr):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.mgr = mgr
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getSessionObject(self, vbox):
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync return self.mgr.platform.getSessionObject(vbox)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsyncclass VirtualBoxManager:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def __init__(self, style, platparams):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync if style is None:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync if sys.platform == 'win32':
08122b11035de1e54ce1e665dff7260fc548db72vboxsync style = "MSCOM"
08122b11035de1e54ce1e665dff7260fc548db72vboxsync else:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync style = "XPCOM"
08122b11035de1e54ce1e665dff7260fc548db72vboxsync try:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync exec "self.platform = Platform"+style+"(platparams)"
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.vbox = self.platform.getVirtualBox()
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.mgr = SessionManager(self)
c65e2fedaf400b449a85ae6db7b84858f2613708vboxsync self.constants = VirtualBoxReflectionInfo()
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.type = self.platform.getType()
08122b11035de1e54ce1e665dff7260fc548db72vboxsync self.remote = self.platform.getRemote()
08122b11035de1e54ce1e665dff7260fc548db72vboxsync except Exception,e:
08122b11035de1e54ce1e665dff7260fc548db72vboxsync print "init exception: ",e
08122b11035de1e54ce1e665dff7260fc548db72vboxsync traceback.print_exc()
08122b11035de1e54ce1e665dff7260fc548db72vboxsync raise e
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getArray(self, obj, field):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return self.platform.getArray(obj, field)
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def getVirtualBox(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync return self.platform.getVirtualBox()
08122b11035de1e54ce1e665dff7260fc548db72vboxsync
08122b11035de1e54ce1e665dff7260fc548db72vboxsync def __del__(self):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync if hasattr(self, "vbox"):
08122b11035de1e54ce1e665dff7260fc548db72vboxsync del self.vbox
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync def initPerThread(self):
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync self.platform.initPerThread()
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync def deinitPerThread(self):
2fd917a77df587742609eaa229c7cf4922458ae8vboxsync self.platform.deinitPerThread()