home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Aplikacje_64-bitowe / VirtualBox / VirtualBox-4.1.2-73507-Win.exe / file___init__.py next >
Encoding:
Python Source  |  2010-08-16  |  20.5 KB  |  612 lines

  1. #
  2. # Copyright (C) 2009 Oracle Corporation
  3. #
  4. # This file is part of VirtualBox Open Source Edition (OSE), as
  5. # available from http://www.virtualbox.org. This file is free software;
  6. # you can redistribute it and/or modify it under the terms of the GNU
  7. # General Public License (GPL) as published by the Free Software
  8. # Foundation, in version 2 as it comes in the "COPYING" file of the
  9. # VirtualBox OSE distribution. VirtualBox OSE is distributed in the
  10. # hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  11. #
  12. import sys,os
  13. import traceback
  14.  
  15. # To set Python bitness on OSX use 'export VERSIONER_PYTHON_PREFER_32_BIT=yes'
  16.  
  17. VboxBinDir = os.environ.get("VBOX_PROGRAM_PATH", None)
  18. VboxSdkDir = os.environ.get("VBOX_SDK_PATH", None)
  19.  
  20. if VboxBinDir is None:
  21.     # Will be set by the installer
  22.     VboxBinDir = "%VBOX_INSTALL_PATH%"
  23.  
  24. if VboxSdkDir is None:
  25.     # Will be set by the installer
  26.     VboxSdkDir = "%VBOX_SDK_PATH%"
  27.  
  28. os.environ["VBOX_PROGRAM_PATH"] = VboxBinDir
  29. os.environ["VBOX_SDK_PATH"] = VboxSdkDir
  30. sys.path.append(VboxBinDir)
  31.  
  32. from VirtualBox_constants import VirtualBoxReflectionInfo
  33.  
  34. class PerfCollector:
  35.     """ This class provides a wrapper over IPerformanceCollector in order to
  36.     get more 'pythonic' interface.
  37.  
  38.     To begin collection of metrics use setup() method.
  39.  
  40.     To get collected data use query() method.
  41.  
  42.     It is possible to disable metric collection without changing collection
  43.     parameters with disable() method. The enable() method resumes metric
  44.     collection.
  45.     """
  46.  
  47.     def __init__(self, mgr, vbox):
  48.         """ Initializes the instance.
  49.  
  50.         """
  51.         self.mgr = mgr
  52.         self.isMscom = (mgr.type == 'MSCOM')
  53.         self.collector = vbox.performanceCollector
  54.  
  55.     def setup(self, names, objects, period, nsamples):
  56.         """ Discards all previously collected values for the specified
  57.         metrics, sets the period of collection and the number of retained
  58.         samples, enables collection.
  59.         """
  60.         self.collector.setupMetrics(names, objects, period, nsamples)
  61.  
  62.     def enable(self, names, objects):
  63.         """ Resumes metric collection for the specified metrics.
  64.         """
  65.         self.collector.enableMetrics(names, objects)
  66.  
  67.     def disable(self, names, objects):
  68.         """ Suspends metric collection for the specified metrics.
  69.         """
  70.         self.collector.disableMetrics(names, objects)
  71.  
  72.     def query(self, names, objects):
  73.         """ Retrieves collected metric values as well as some auxiliary
  74.         information. Returns an array of dictionaries, one dictionary per
  75.         metric. Each dictionary contains the following entries:
  76.         'name': metric name
  77.         'object': managed object this metric associated with
  78.         'unit': unit of measurement
  79.         'scale': divide 'values' by this number to get float numbers
  80.         'values': collected data
  81.         'values_as_string': pre-processed values ready for 'print' statement
  82.         """
  83.         # Get around the problem with input arrays returned in output
  84.         # parameters (see #3953) for MSCOM.
  85.         if self.isMscom:
  86.             (values, names, objects, names_out, objects_out, units, scales, sequence_numbers,
  87.                 indices, lengths) = self.collector.queryMetricsData(names, objects)
  88.         else:
  89.             (values, names_out, objects_out, units, scales, sequence_numbers,
  90.                 indices, lengths) = self.collector.queryMetricsData(names, objects)
  91.         out = []
  92.         for i in xrange(0, len(names_out)):
  93.             scale = int(scales[i])
  94.             if scale != 1:
  95.                 fmt = '%.2f%s'
  96.             else:
  97.                 fmt = '%d %s'
  98.             out.append({
  99.                 'name':str(names_out[i]),
  100.                 'object':str(objects_out[i]),
  101.                 'unit':str(units[i]),
  102.                 'scale':scale,
  103.                 'values':[int(values[j]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))],
  104.                 'values_as_string':'['+', '.join([fmt % (int(values[j])/scale, units[i]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))])+']'
  105.             })
  106.         return out
  107.  
  108. def ComifyName(name):
  109.     return name[0].capitalize()+name[1:]
  110.  
  111. _COMForward = { 'getattr' : None,
  112.                 'setattr' : None}
  113.  
  114. def CustomGetAttr(self, attr):
  115.     # fastpath
  116.     if self.__class__.__dict__.get(attr) != None:
  117.         return self.__class__.__dict__.get(attr)
  118.  
  119.     # try case-insensitivity workaround for class attributes (COM methods)
  120.     for k in self.__class__.__dict__.keys():
  121.         if k.lower() == attr.lower():
  122.             self.__class__.__dict__[attr] = self.__class__.__dict__[k]
  123.             return getattr(self, k)
  124.     try:
  125.         return _COMForward['getattr'](self,ComifyName(attr))
  126.     except AttributeError:
  127.         return _COMForward['getattr'](self,attr)
  128.  
  129. def CustomSetAttr(self, attr, value):
  130.     try:
  131.         return _COMForward['setattr'](self, ComifyName(attr), value)
  132.     except AttributeError:
  133.         return _COMForward['setattr'](self, attr, value)
  134.  
  135. class PlatformMSCOM:
  136.     # Class to fake access to constants in style of foo.bar.boo
  137.     class ConstantFake:
  138.         def __init__(self, parent, name):
  139.             self.__dict__['_parent'] = parent
  140.             self.__dict__['_name'] = name
  141.             self.__dict__['_consts'] = {}
  142.             try:
  143.                 self.__dict__['_depth']=parent.__dict__['_depth']+1
  144.             except:
  145.                 self.__dict__['_depth']=0
  146.                 if self.__dict__['_depth'] > 4:
  147.                     raise AttributeError
  148.  
  149.         def __getattr__(self, attr):
  150.             import win32com
  151.             from win32com.client import constants
  152.  
  153.             if attr.startswith("__"):
  154.                 raise AttributeError
  155.  
  156.             consts = self.__dict__['_consts']
  157.  
  158.             fake = consts.get(attr, None)
  159.             if fake != None:
  160.                return fake
  161.             try:
  162.                name = self.__dict__['_name']
  163.                parent = self.__dict__['_parent']
  164.                while parent != None:
  165.                   if parent._name is not None:
  166.                     name = parent._name+'_'+name
  167.                   parent = parent._parent
  168.  
  169.                if name is not None:
  170.                   name += "_" + attr
  171.                else:
  172.                   name = attr
  173.                return win32com.client.constants.__getattr__(name)
  174.             except AttributeError,e:
  175.                fake = PlatformMSCOM.ConstantFake(self, attr)
  176.                consts[attr] = fake
  177.                return fake
  178.  
  179.  
  180.     class InterfacesWrapper:
  181.             def __init__(self):
  182.                 self.__dict__['_rootFake'] = PlatformMSCOM.ConstantFake(None, None)
  183.  
  184.             def __getattr__(self, a):
  185.                 import win32com
  186.                 from win32com.client import constants
  187.                 if a.startswith("__"):
  188.                     raise AttributeError
  189.                 try:
  190.                     return win32com.client.constants.__getattr__(a)
  191.                 except AttributeError,e:
  192.                     return self.__dict__['_rootFake'].__getattr__(a)
  193.  
  194.     VBOX_TLB_GUID  = '{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}'
  195.     VBOX_TLB_LCID  = 0
  196.     VBOX_TLB_MAJOR = 1
  197.     VBOX_TLB_MINOR = 0
  198.  
  199.     def __init__(self, params):
  200.             from win32com import universal
  201.             from win32com.client import gencache, DispatchBaseClass
  202.             from win32com.client import constants, getevents
  203.             import win32com
  204.             import pythoncom
  205.             import win32api
  206.             from win32con import DUPLICATE_SAME_ACCESS
  207.             from win32api import GetCurrentThread,GetCurrentThreadId,DuplicateHandle,GetCurrentProcess
  208.             import threading
  209.             pid = GetCurrentProcess()
  210.             self.tid = GetCurrentThreadId()
  211.             handle = DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS)
  212.             self.handles = []
  213.             self.handles.append(handle)
  214.             _COMForward['getattr'] = DispatchBaseClass.__dict__['__getattr__']
  215.             DispatchBaseClass.__dict__['__getattr__'] = CustomGetAttr
  216.             _COMForward['setattr'] = DispatchBaseClass.__dict__['__setattr__']
  217.             DispatchBaseClass.__dict__['__setattr__'] = CustomSetAttr
  218.             win32com.client.gencache.EnsureDispatch('VirtualBox.Session')
  219.             win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox')
  220.             self.oIntCv = threading.Condition()
  221.             self.fInterrupted = False;
  222.  
  223.     def getSessionObject(self, vbox):
  224.         import win32com
  225.         from win32com.client import Dispatch
  226.         return win32com.client.Dispatch("VirtualBox.Session")
  227.  
  228.     def getVirtualBox(self):
  229.         import win32com
  230.         from win32com.client import Dispatch
  231.         return win32com.client.Dispatch("VirtualBox.VirtualBox")
  232.  
  233.     def getType(self):
  234.         return 'MSCOM'
  235.  
  236.     def getRemote(self):
  237.         return False
  238.  
  239.     def getArray(self, obj, field):
  240.         return obj.__getattr__(field)
  241.  
  242.     def initPerThread(self):
  243.         import pythoncom
  244.         pythoncom.CoInitializeEx(0)
  245.  
  246.     def deinitPerThread(self):
  247.         import pythoncom
  248.         pythoncom.CoUninitialize()
  249.  
  250.     def createListener(self, impl, arg):
  251.         d = {}
  252.         d['BaseClass'] = impl
  253.         d['arg'] = arg
  254.         d['tlb_guid'] = PlatformMSCOM.VBOX_TLB_GUID
  255.         str = ""
  256.         str += "import win32com.server.util\n"
  257.         str += "import pythoncom\n"
  258.  
  259.         str += "class ListenerImpl(BaseClass):\n"
  260.         str += "   _com_interfaces_ = ['IEventListener']\n"
  261.         str += "   _typelib_guid_ = tlb_guid\n"
  262.         str += "   _typelib_version_ = 1, 0\n"
  263.         str += "   _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER\n"
  264.         # Maybe we'd better implement Dynamic invoke policy, to be more flexible here
  265.         str += "   _reg_policy_spec_ = 'win32com.server.policy.EventHandlerPolicy'\n"
  266.  
  267.         # capitalized version of listener method
  268.         str += "   HandleEvent=BaseClass.handleEvent\n"
  269.         str += "   def __init__(self): BaseClass.__init__(self, arg)\n"
  270.         str += "result = win32com.server.util.wrap(ListenerImpl())\n"
  271.         exec (str,d,d)
  272.         return d['result']
  273.  
  274.     def waitForEvents(self, timeout):
  275.         from win32api import GetCurrentThreadId
  276.         from win32event import INFINITE
  277.         from win32event import MsgWaitForMultipleObjects, \
  278.                                QS_ALLINPUT, WAIT_TIMEOUT, WAIT_OBJECT_0
  279.         from pythoncom import PumpWaitingMessages
  280.         import types
  281.  
  282.         if not isinstance(timeout, types.IntType):
  283.             raise TypeError("The timeout argument is not an integer")
  284.         if (self.tid != GetCurrentThreadId()):
  285.             raise Exception("wait for events from the same thread you inited!")
  286.  
  287.         if timeout < 0:     cMsTimeout = INFINITE
  288.         else:               cMsTimeout = timeout
  289.         rc = MsgWaitForMultipleObjects(self.handles, 0, cMsTimeout, QS_ALLINPUT)
  290.         if rc >= WAIT_OBJECT_0 and rc < WAIT_OBJECT_0+len(self.handles):
  291.             # is it possible?
  292.             rc = 2;
  293.         elif rc==WAIT_OBJECT_0 + len(self.handles):
  294.             # Waiting messages
  295.             PumpWaitingMessages()
  296.             rc = 0;
  297.         else:
  298.             # Timeout
  299.             rc = 1;
  300.  
  301.         # check for interruption
  302.         self.oIntCv.acquire()
  303.         if self.fInterrupted:
  304.             self.fInterrupted = False
  305.             rc = 1;
  306.         self.oIntCv.release()
  307.  
  308.         return rc;
  309.  
  310.     def interruptWaitEvents(self):
  311.         """
  312.         Basically a python implementation of EventQueue::postEvent().
  313.  
  314.         The magic value must be in sync with the C++ implementation or this
  315.         won't work.
  316.  
  317.         Note that because of this method we cannot easily make use of a
  318.         non-visible Window to handle the message like we would like to do.
  319.         """
  320.         from win32api import PostThreadMessage
  321.         from win32con import WM_USER
  322.         self.oIntCv.acquire()
  323.         self.fInterrupted = True
  324.         self.oIntCv.release()
  325.         try:
  326.             PostThreadMessage(self.tid, WM_USER, None, 0xf241b819)
  327.         except:
  328.             return False;
  329.         return True;
  330.  
  331.     def deinit(self):
  332.         import pythoncom
  333.         from win32file import CloseHandle
  334.  
  335.         for h in self.handles:
  336.            if h is not None:
  337.               CloseHandle(h)
  338.         self.handles = None
  339.         pythoncom.CoUninitialize()
  340.         pass
  341.  
  342.     def queryInterface(self, obj, klazzName):
  343.         from win32com.client import CastTo
  344.         return CastTo(obj, klazzName)
  345.  
  346. class PlatformXPCOM:
  347.     def __init__(self, params):
  348.         sys.path.append(VboxSdkDir+'/bindings/xpcom/python/')
  349.         import xpcom.vboxxpcom
  350.         import xpcom
  351.         import xpcom.components
  352.  
  353.     def getSessionObject(self, vbox):
  354.         import xpcom.components
  355.         return xpcom.components.classes["@virtualbox.org/Session;1"].createInstance()
  356.  
  357.     def getVirtualBox(self):
  358.         import xpcom.components
  359.         return xpcom.components.classes["@virtualbox.org/VirtualBox;1"].createInstance()
  360.  
  361.     def getType(self):
  362.         return 'XPCOM'
  363.  
  364.     def getRemote(self):
  365.         return False
  366.  
  367.     def getArray(self, obj, field):
  368.         return obj.__getattr__('get'+ComifyName(field))()
  369.  
  370.     def initPerThread(self):
  371.         import xpcom
  372.         xpcom._xpcom.AttachThread()
  373.  
  374.     def deinitPerThread(self):
  375.         import xpcom
  376.         xpcom._xpcom.DetachThread()
  377.  
  378.     def createListener(self, impl, arg):
  379.         d = {}
  380.         d['BaseClass'] = impl
  381.         d['arg'] = arg
  382.         str = ""
  383.         str += "import xpcom.components\n"
  384.         str += "class ListenerImpl(BaseClass):\n"
  385.         str += "   _com_interfaces_ = xpcom.components.interfaces.IEventListener\n"
  386.         str += "   def __init__(self): BaseClass.__init__(self, arg)\n"
  387.         str += "result = ListenerImpl()\n"
  388.         exec (str,d,d)
  389.         return d['result']
  390.  
  391.     def waitForEvents(self, timeout):
  392.         import xpcom
  393.         return xpcom._xpcom.WaitForEvents(timeout)
  394.  
  395.     def interruptWaitEvents(self):
  396.         import xpcom
  397.         return xpcom._xpcom.InterruptWait()
  398.  
  399.     def deinit(self):
  400.         import xpcom
  401.         xpcom._xpcom.DeinitCOM()
  402.  
  403.     def queryInterface(self, obj, klazzName):
  404.         import xpcom.components
  405.         return obj.queryInterface(getattr(xpcom.components.interfaces, klazzName))
  406.  
  407. class PlatformWEBSERVICE:
  408.     def __init__(self, params):
  409.         sys.path.append(os.path.join(VboxSdkDir,'bindings', 'webservice', 'python', 'lib'))
  410.         #import VirtualBox_services
  411.         import VirtualBox_wrappers
  412.         from VirtualBox_wrappers import IWebsessionManager2
  413.  
  414.         if params is not None:
  415.             self.user = params.get("user", "")
  416.             self.password = params.get("password", "")
  417.             self.url = params.get("url", "")
  418.         else:
  419.             self.user = ""
  420.             self.password = ""
  421.             self.url = None
  422.         self.vbox = None
  423.  
  424.     def getSessionObject(self, vbox):
  425.         return self.wsmgr.getSessionObject(vbox)
  426.  
  427.     def getVirtualBox(self):
  428.         return self.connect(self.url, self.user, self.password)
  429.  
  430.     def connect(self, url, user, passwd):
  431.         if self.vbox is not None:
  432.              self.disconnect()
  433.         from VirtualBox_wrappers import IWebsessionManager2
  434.         if url is None:
  435.             url = ""
  436.         self.url = url
  437.         if user is None:
  438.             user = ""
  439.         self.user = user
  440.         if passwd is None:
  441.             passwd = ""
  442.         self.password = passwd
  443.         self.wsmgr = IWebsessionManager2(self.url)
  444.         self.vbox = self.wsmgr.logon(self.user, self.password)
  445.         if not self.vbox.handle:
  446.             raise Exception("cannot connect to '"+self.url+"' as '"+self.user+"'")
  447.         return self.vbox
  448.  
  449.     def disconnect(self):
  450.         if self.vbox is not None and self.wsmgr is not None:
  451.                 self.wsmgr.logoff(self.vbox)
  452.                 self.vbox = None
  453.                 self.wsmgr = None
  454.  
  455.     def getType(self):
  456.         return 'WEBSERVICE'
  457.  
  458.     def getRemote(self):
  459.         return True
  460.  
  461.     def getArray(self, obj, field):
  462.         return obj.__getattr__(field)
  463.  
  464.     def initPerThread(self):
  465.         pass
  466.  
  467.     def deinitPerThread(self):
  468.         pass
  469.  
  470.     def createListener(self, impl, arg):
  471.         raise Exception("no active listeners for webservices")
  472.  
  473.     def waitForEvents(self, timeout):
  474.         # Webservices cannot do that yet
  475.         return 2;
  476.  
  477.     def interruptWaitEvents(self, timeout):
  478.         # Webservices cannot do that yet
  479.         return False;
  480.  
  481.     def deinit(self):
  482.         try:
  483.            disconnect()
  484.         except:
  485.            pass
  486.  
  487.     def queryInterface(self, obj, klazzName):
  488.         d = {}
  489.         d['obj'] = obj
  490.         str = ""
  491.         str += "from VirtualBox_wrappers import "+klazzName+"\n"
  492.         str += "result = "+klazzName+"(obj.mgr,obj.handle)\n"
  493.         # wrong, need to test if class indeed implements this interface
  494.         exec (str,d,d)
  495.         return d['result']
  496.  
  497. class SessionManager:
  498.     def __init__(self, mgr):
  499.         self.mgr = mgr
  500.  
  501.     def getSessionObject(self, vbox):
  502.         return self.mgr.platform.getSessionObject(vbox)
  503.  
  504. class VirtualBoxManager:
  505.     def __init__(self, style, platparams):
  506.         if style is None:
  507.             if sys.platform == 'win32':
  508.                 style = "MSCOM"
  509.             else:
  510.                 style = "XPCOM"
  511.  
  512.  
  513.         exec "self.platform = Platform"+style+"(platparams)"
  514.         # for webservices, enums are symbolic
  515.         self.constants = VirtualBoxReflectionInfo(style == "WEBSERVICE")
  516.         self.type = self.platform.getType()
  517.         self.remote = self.platform.getRemote()
  518.         self.style = style
  519.         self.mgr = SessionManager(self)
  520.  
  521.         try:
  522.             self.vbox = self.platform.getVirtualBox()
  523.         except NameError,ne:
  524.             print "Installation problem: check that appropriate libs in place"
  525.             traceback.print_exc()
  526.             raise ne
  527.         except Exception,e:
  528.             print "init exception: ",e
  529.             traceback.print_exc()
  530.             if self.remote:
  531.                 self.vbox = None
  532.             else:
  533.                 raise e
  534.  
  535.     def getArray(self, obj, field):
  536.         return self.platform.getArray(obj, field)
  537.  
  538.     def getVirtualBox(self):
  539.         return  self.platform.getVirtualBox()
  540.  
  541.     def __del__(self):
  542.         self.deinit()
  543.  
  544.     def deinit(self):
  545.         if hasattr(self, "vbox"):
  546.             del self.vbox
  547.             self.vbox = None
  548.         if hasattr(self, "platform"):
  549.             self.platform.deinit()
  550.             self.platform = None
  551.  
  552.     def initPerThread(self):
  553.         self.platform.initPerThread()
  554.  
  555.     def openMachineSession(self, mach, permitSharing = True):
  556.          session = self.mgr.getSessionObject(self.vbox)
  557.          if permitSharing:
  558.              type = self.constants.LockType_Shared
  559.          else:
  560.              type = self.constants.LockType_Write
  561.          mach.lockMachine(session, type)
  562.          return session
  563.  
  564.     def closeMachineSession(self, session):
  565.         if session is not None:
  566.             session.unlockMachine()
  567.  
  568.     def deinitPerThread(self):
  569.         self.platform.deinitPerThread()
  570.  
  571.     def createListener(self, impl, arg = None):
  572.         return self.platform.createListener(impl, arg)
  573.  
  574.     def waitForEvents(self, timeout):
  575.         """
  576.         Wait for events to arrive and process them.
  577.  
  578.         The timeout is in milliseconds.  A negative value means waiting for
  579.         ever, while 0 does not wait at all.
  580.  
  581.         Returns 0 if events was processed.
  582.         Returns 1 if timed out or interrupted in some way.
  583.         Returns 2 on error (like not supported for web services).
  584.  
  585.         Raises an exception if the calling thread is not the main thread (the one
  586.         that initialized VirtualBoxManager) or if the time isn't an integer.
  587.         """
  588.         return self.platform.waitForEvents(timeout)
  589.  
  590.     def interruptWaitEvents(self):
  591.         """
  592.         Interrupt a waitForEvents call.
  593.         This is normally called from a worker thread.
  594.  
  595.         Returns True on success, False on failure.
  596.         """
  597.         return self.platform.interruptWaitEvents()
  598.  
  599.     def getPerfCollector(self, vbox):
  600.         return PerfCollector(self, vbox)
  601.  
  602.     def getBinDir(self):
  603.         global VboxBinDir
  604.         return VboxBinDir
  605.  
  606.     def getSdkDir(self):
  607.         global VboxSdkDir
  608.         return VboxSdkDir
  609.  
  610.     def queryInterface(self, obj, klazzName):
  611.         return self.platform.queryInterface(obj, klazzName)
  612.