VirtualBox

source: vbox/trunk/src/VBox/Main/glue/vboxapi.py@ 20894

Last change on this file since 20894 was 20818, checked in by vboxsync, 16 years ago

Python: generate capitalized version of callbacks on Windows, now Win32 callbacks work just fine

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.9 KB
Line 
1#
2# Copyright (C) 2009 Sun Microsystems, Inc.
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# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
13# Clara, CA 95054 USA or visit http://www.sun.com if you need
14# additional information or have any questions.
15#
16import sys,os
17import traceback
18
19VboxBinDir = os.environ.get("VBOX_PROGRAM_PATH", None)
20VboxSdkDir = os.environ.get("VBOX_SDK_PATH", None)
21
22if VboxBinDir is None:
23 # Will be set by the installer
24 VboxBinDir = "%VBOX_INSTALL_PATH%"
25
26if VboxSdkDir is None:
27 VboxSdkDir = VboxBinDir+"/sdk"
28
29os.environ["VBOX_PROGRAM_PATH"] = VboxBinDir
30os.environ["VBOX_SDK_PATH"] = VboxSdkDir
31sys.path.append(VboxBinDir)
32
33from VirtualBox_constants import VirtualBoxReflectionInfo
34
35class PlatformMSCOM:
36 # Class to fake access to constants in style of foo.bar.boo
37 class ConstantFake:
38 def __init__(self, parent, name):
39 self.__dict__['_parent'] = parent
40 self.__dict__['_name'] = name
41 self.__dict__['_consts'] = {}
42 try:
43 self.__dict__['_depth']=parent.__dict__['_depth']+1
44 except:
45 self.__dict__['_depth']=0
46 if self.__dict__['_depth'] > 4:
47 raise AttributeError
48
49 def __getattr__(self, attr):
50 import win32com
51 from win32com.client import constants
52
53 if attr.startswith("__"):
54 raise AttributeError
55
56 consts = self.__dict__['_consts']
57
58 fake = consts.get(attr, None)
59 if fake != None:
60 return fake
61 try:
62 name = self.__dict__['_name']
63 parent = self.__dict__['_parent']
64 while parent != None:
65 if parent._name is not None:
66 name = parent._name+'_'+name
67 parent = parent._parent
68
69 if name is not None:
70 name += "_" + attr
71 else:
72 name = attr
73 return win32com.client.constants.__getattr__(name)
74 except AttributeError,e:
75 fake = PlatformMSCOM.ConstantFake(self, attr)
76 consts[attr] = fake
77 return fake
78
79
80 class InterfacesWrapper:
81 def __init__(self):
82 self.__dict__['_rootFake'] = PlatformMSCOM.ConstantFake(None, None)
83
84 def __getattr__(self, a):
85 import win32com
86 from win32com.client import constants
87 if a.startswith("__"):
88 raise AttributeError
89 try:
90 return win32com.client.constants.__getattr__(a)
91 except AttributeError,e:
92 return self.__dict__['_rootFake'].__getattr__(a)
93
94 VBOX_TLB_GUID = '{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}'
95 VBOX_TLB_LCID = 0
96 VBOX_TLB_MAJOR = 1
97 VBOX_TLB_MINOR = 0
98
99 def __init__(self, params):
100 from win32com import universal
101 from win32com.client import gencache, DispatchWithEvents, Dispatch
102 from win32com.client import constants, getevents
103 import win32com
104 import pythoncom
105 import win32api
106 self.constants = PlatformMSCOM.InterfacesWrapper()
107 from win32con import DUPLICATE_SAME_ACCESS
108 from win32api import GetCurrentThread,GetCurrentThreadId,DuplicateHandle,GetCurrentProcess
109 pid = GetCurrentProcess()
110 self.tid = GetCurrentThreadId()
111 handle = DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS)
112 self.handles = []
113 self.handles.append(handle)
114
115
116 def getSessionObject(self, vbox):
117 import win32com
118 from win32com.client import Dispatch
119 return win32com.client.Dispatch("VirtualBox.Session")
120
121 def getVirtualBox(self):
122 import win32com
123 from win32com.client import Dispatch
124 return win32com.client.Dispatch("VirtualBox.VirtualBox")
125
126 def getConstants(self):
127 return self.constants
128
129 def getType(self):
130 return 'MSCOM'
131
132 def getRemote(self):
133 return False
134
135 def getArray(self, obj, field):
136 return obj.__getattr__(field)
137
138 def initPerThread(self):
139 import pythoncom
140 pythoncom.CoInitializeEx(0)
141
142 def deinitPerThread(self):
143 import pythoncom
144 pythoncom.CoUninitialize()
145
146 def createCallback(self, iface, impl, arg):
147 d = {}
148 d['BaseClass'] = impl
149 d['arg'] = arg
150 d['tlb_guid'] = PlatformMSCOM.VBOX_TLB_GUID
151 str = ""
152 str += "import win32com.server.util\n"
153 #str += "import win32com.server.register\n"
154 #str += "from win32com import universal\n"
155 str += "import pythoncom\n"
156 #str += "universal.RegisterInterfaces(tlb_guid, 0, 1, 0, ['"+iface+"'])\n"
157
158 str += "class "+iface+"Impl(BaseClass):\n"
159 str += " _com_interfaces_ = ['"+iface+"']\n"
160 str += " _typelib_guid_ = tlb_guid\n"
161 str += " _typelib_version_ = 1, 0\n"
162 #str += " _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER\n"
163 #str += " _reg_clsid_ = '{F21202A2-959A-4149-B1C3-68B9013F3335}'\n"
164 #str += " _reg_progid_ = 'VirtualBox."+iface+"Impl'\n"
165 #str += " _reg_desc_ = 'Generated callback implementation class'\n"
166 #str += " _reg_policy_spec_ = 'win32com.server.policy.EventHandlerPolicy'\n"
167
168 # generate capitalized version of callbacks - that's how Python COM
169 # looks them up on Windows
170 for m in dir(impl):
171 if m.startswith("on"):
172 str += " "+m[0].capitalize()+m[1:]+"=BaseClass."+m+"\n"
173
174 str += " def __init__(self): BaseClass.__init__(self, arg)\n"
175 #str += "win32com.server.register.UseCommandLine("+iface+"Impl)\n"
176
177 str += "result = win32com.server.util.wrap("+iface+"Impl())\n"
178 exec (str,d,d)
179 return d['result']
180
181 def waitForEvents(self, timeout):
182 from win32api import GetCurrentThreadId
183 from win32event import MsgWaitForMultipleObjects, \
184 QS_ALLINPUT, WAIT_TIMEOUT, WAIT_OBJECT_0
185 from pythoncom import PumpWaitingMessages
186
187 if (self.tid != GetCurrentThreadId()):
188 raise Exception("wait for events from the same thread you inited!")
189
190 rc = MsgWaitForMultipleObjects(self.handles, 0, timeout, QS_ALLINPUT)
191 if rc >= WAIT_OBJECT_0 and rc < WAIT_OBJECT_0+len(self.handles):
192 # is it possible?
193 print "how come?"
194 pass
195 elif rc==WAIT_OBJECT_0 + len(self.handles):
196 # Waiting messages
197 PumpWaitingMessages()
198 else:
199 # Timeout
200 pass
201
202 def deinit(self):
203 import pythoncom
204 from win32file import CloseHandle
205
206 for h in self.handles:
207 if h is not None:
208 CloseHandle(h)
209 self.handles = None
210 pythoncom.CoUninitialize()
211 pass
212
213class PlatformXPCOM:
214 def __init__(self, params):
215 sys.path.append(VboxSdkDir+'/bindings/xpcom/python/')
216 import xpcom.vboxxpcom
217 import xpcom
218 import xpcom.components
219
220 def getSessionObject(self, vbox):
221 import xpcom.components
222 return xpcom.components.classes["@virtualbox.org/Session;1"].createInstance()
223
224 def getVirtualBox(self):
225 import xpcom.components
226 return xpcom.components.classes["@virtualbox.org/VirtualBox;1"].createInstance()
227
228 def getConstants(self):
229 import xpcom.components
230 return xpcom.components.interfaces
231
232 def getType(self):
233 return 'XPCOM'
234
235 def getRemote(self):
236 return False
237
238 def getArray(self, obj, field):
239 return obj.__getattr__('get'+field.capitalize())()
240
241 def initPerThread(self):
242 pass
243
244 def deinitPerThread(self):
245 pass
246
247 def createCallback(self, iface, impl, arg):
248 d = {}
249 d['BaseClass'] = impl
250 d['arg'] = arg
251 str = ""
252 str += "import xpcom.components\n"
253 str += "class "+iface+"Impl(BaseClass):\n"
254 str += " _com_interfaces_ = xpcom.components.interfaces."+iface+"\n"
255 str += " def __init__(self): BaseClass.__init__(self, arg)\n"
256 str += "result = "+iface+"Impl()\n"
257 exec (str,d,d)
258 return d['result']
259
260 def waitForEvents(self, timeout):
261 import xpcom
262 xpcom._xpcom.WaitForEvents(timeout)
263
264 def deinit(self):
265 import xpcom
266 xpcom._xpcom.DeinitCOM()
267
268class PlatformWEBSERVICE:
269 def __init__(self, params):
270 sys.path.append(VboxSdkDir+'/bindings/webservice/python/lib')
271 import VirtualBox_services
272 import VirtualBox_wrappers
273 from VirtualBox_wrappers import IWebsessionManager2
274 if params is not None:
275 self.user = params.get("user", "")
276 self.password = params.get("password", "")
277 self.url = params.get("url", "")
278 else:
279 self.user = ""
280 self.password = ""
281 self.url = None
282 self.wsmgr = IWebsessionManager2(self.url)
283
284 def getSessionObject(self, vbox):
285 return self.wsmgr.getSessionObject(vbox)
286
287 def getVirtualBox(self):
288 return self.wsmgr.logon(self.user, self.password)
289
290 def getConstants(self):
291 return None
292
293 def getType(self):
294 return 'WEBSERVICE'
295
296 def getRemote(self):
297 return True
298
299 def getArray(self, obj, field):
300 return obj.__getattr__(field)
301
302 def initPerThread(self):
303 pass
304
305 def deinitPerThread(self):
306 pass
307
308 def createCallback(self, iface, impl, arg):
309 raise Exception("no callbacks for webservices")
310
311 def waitForEvents(self, timeout):
312 # Webservices cannot do that
313 pass
314
315 def deinit(self):
316 # should we do something about it?
317 pass
318
319class SessionManager:
320 def __init__(self, mgr):
321 self.mgr = mgr
322
323 def getSessionObject(self, vbox):
324 return self.mgr.platform.getSessionObject(vbox)
325
326class VirtualBoxManager:
327 def __init__(self, style, platparams):
328 if style is None:
329 if sys.platform == 'win32':
330 style = "MSCOM"
331 else:
332 style = "XPCOM"
333 try:
334 exec "self.platform = Platform"+style+"(platparams)"
335 self.vbox = self.platform.getVirtualBox()
336 self.mgr = SessionManager(self)
337 self.constants = VirtualBoxReflectionInfo()
338 self.type = self.platform.getType()
339 self.remote = self.platform.getRemote()
340 except Exception,e:
341 print "init exception: ",e
342 traceback.print_exc()
343 raise e
344
345 def getArray(self, obj, field):
346 return self.platform.getArray(obj, field)
347
348 def getVirtualBox(self):
349 return self.platform.getVirtualBox()
350
351 def __del__(self):
352 deinit(self)
353
354 def deinit(self):
355 if hasattr(self, "vbox"):
356 del self.vbox
357 if hasattr(self, "platform"):
358 self.platform.deinit()
359
360 def initPerThread(self):
361 self.platform.initPerThread()
362
363 def openMachineSession(self, machineId):
364 session = self.mgr.getSessionObject(self.vbox)
365 self.vbox.openSession(session, machineId)
366 return session
367
368 def closeMachineSession(self, session):
369 session.close()
370
371 def deinitPerThread(self):
372 self.platform.deinitPerThread()
373
374 def createCallback(self, iface, impl, arg):
375 return self.platform.createCallback(iface, impl, arg)
376
377 def waitForEvents(self, timeout):
378 return self.platform.waitForEvents(timeout)
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette