Changeset 47981 in vbox for trunk/src/VBox
- Timestamp:
- Aug 22, 2013 12:47:00 AM (11 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxShell/vboxshell.py
r47979 r47981 205 205 206 206 def printErr(_ctx, e): 207 print colored(str(e), 'red') 207 oVBoxMgr = _ctx['global']; 208 if oVBoxMgr.errIsOurXcptKind(e): 209 print colored('%s: %s' % (oVBoxMgr.errToString(e), oVBoxMgr.errGetMessage(e)), 'red'); 210 else: 211 print colored(str(e), 'red') 208 212 209 213 def reportError(_ctx, progress): -
trunk/src/VBox/Main/glue/vboxapi.py
r47979 r47981 131 131 # 132 132 def ComifyName(name): 133 return name[0].capitalize() +name[1:]133 return name[0].capitalize() + name[1:] 134 134 135 135 … … 141 141 } 142 142 143 def CustomGetAttr(self, attr): 144 # fastpath 145 if self.__class__.__dict__.get(attr) != None: 146 return self.__class__.__dict__.get(attr) 147 148 # try case-insensitivity workaround for class attributes (COM methods) 149 for k in self.__class__.__dict__.keys(): 150 if k.lower() == attr.lower(): 151 self.__class__.__dict__[attr] = self.__class__.__dict__[k] 152 return getattr(self, k) 143 def _CustomGetAttr(self, sAttr): 144 """ Our getattr replacement for DispatchBaseClass. """ 145 # Fastpath. 146 oRet = self.__class__.__dict__.get(sAttr); 147 if oRet != None: 148 return oRet; 149 150 # Try case-insensitivity workaround for class attributes (COM methods). 151 sAttrLower = sAttr.lower(); 152 for sKey in self.__class__.__dict__.keys(): 153 if sKey.lower() == sAttrLower: 154 self.__class__.__dict__[sAttr] = self.__class__.__dict__[sKey] 155 return getattr(self, sKey) 156 157 # Slow path. 153 158 try: 154 return _g_dCOMForward['getattr'](self, ComifyName( attr))159 return _g_dCOMForward['getattr'](self, ComifyName(sAttr)) 155 160 except AttributeError: 156 return _g_dCOMForward['getattr'](self, attr) 157 158 def CustomSetAttr(self, attr, value): 161 return _g_dCOMForward['getattr'](self, sAttr) 162 163 def _CustomSetAttr(self, sAttr, oValue): 164 """ Our setattr replacement for DispatchBaseClass. """ 159 165 try: 160 return _g_dCOMForward['setattr'](self, ComifyName( attr), value)166 return _g_dCOMForward['setattr'](self, ComifyName(sAttr), oValue) 161 167 except AttributeError: 162 return _g_dCOMForward['setattr'](self, attr, value)168 return _g_dCOMForward['setattr'](self, sAttr, oValue) 163 169 164 170 … … 286 292 """ 287 293 return None; 294 295 # 296 # Error (exception) access methods. 297 # 298 299 def errGetStatus(self, oXcpt): 300 """ 301 Returns the COM status code from the VBox API given exception. 302 """ 303 return None; 304 305 def errIsDeadInterface(self, oXcpt): 306 """ 307 Returns True if the exception indicates that the interface is dead, False if not. 308 """ 309 return False; 310 311 def errIsEqual(oXcpt, hrStatus): 312 """ 313 Checks if the exception oXcpt is equal to the COM/XPCOM status code 314 hrStatus. 315 316 The oXcpt parameter can be any kind of object, we'll just return True 317 if it doesn't behave like a our exception class. 318 319 Will not raise any exception as long as hrStatus and self are not bad. 320 """ 321 try: 322 hrXcpt = self.errGetStatus(oXcpt); 323 except AttributeError: 324 return False; 325 return hrXcpt == hrStatus; 326 327 def errGetMessage(self, oXcpt): 328 """ 329 Returns the best error message found in the COM-like exception. 330 Returns None to fall back on errToString. 331 Raises exception if oXcpt isn't our kind of exception object. 332 """ 333 return None; 334 335 def errGetBaseXcpt(self): 336 """ 337 Returns the base exception class. 338 """ 339 return None; 340 341 def errSetupConstants(self, oDst): 342 """ 343 Copy/whatever all error constants onto oDst. 344 """ 345 return oDst; 346 347 @staticmethod 348 def errCopyErrorConstants(oDst, oSrc): 349 """ 350 Copy everything that looks like error constants from oDst to oSrc. 351 """ 352 for sAttr in dir(oSrc): 353 if sAttr[0].isupper() and (sAttr[1].isupper() or sAttr[1] == '_'): 354 oAttr = getattr(oSrc, sAttr); 355 if type(oAttr) is int: 356 setattr(oDst, sAttr, oAttr); 357 return oDst; 358 288 359 289 360 … … 377 448 import pythoncom 378 449 import win32api 450 import winerror 379 451 from win32con import DUPLICATE_SAME_ACCESS 380 452 from win32api import GetCurrentThread, GetCurrentThreadId, DuplicateHandle, GetCurrentProcess 381 453 import threading 454 455 self.winerror = winerror; 382 456 383 457 pid = GetCurrentProcess() … … 391 465 if _g_dCOMForward['setattr'] is None: 392 466 _g_dCOMForward['getattr'] = DispatchBaseClass.__dict__['__getattr__'] 393 DispatchBaseClass.__dict__['__getattr__'] = CustomGetAttr467 DispatchBaseClass.__dict__['__getattr__'] = _CustomGetAttr 394 468 _g_dCOMForward['setattr'] = DispatchBaseClass.__dict__['__setattr__'] 395 DispatchBaseClass.__dict__['__setattr__'] = CustomSetAttr469 DispatchBaseClass.__dict__['__setattr__'] = _CustomSetAttr 396 470 397 471 # Hack the exception base class so the users doesn't need to check for … … 538 612 return CastTo(oIUnknown, sClassName) 539 613 614 def errGetStatus(self, oXcpt): 615 # The DISP_E_EXCEPTION + excptinfo fun needs checking up, only 616 # empirical info on it so far. 617 hrXcpt = oXcpt.hresult 618 if hrXcpt == self.winerror.DISP_E_EXCEPTION: 619 try: hrXcpt = oXcpt.excepinfo[5]; 620 except: pass; 621 return hrXcpt; 622 623 def errIsDeadInterface(self, oXcpt): 624 return self.errGetStatus(oXcpt) in [ 625 0x800706ba, -2147023174, # RPC_S_SERVER_UNAVAILABLE. 626 0x800706be, -2147023170, # RPC_S_CALL_FAILED. 627 0x800706bf, -2147023169, # RPC_S_CALL_FAILED_DNE. 628 0x80010108, -2147417848, # RPC_E_DISCONNECTED. 629 ]; 630 631 632 def errGetMessage(self, oXcpt): 633 if hasattr(oXcpt, 'excepinfo'): 634 try: 635 if len(oXcpt.excepinfo) >= 3: 636 sRet = oXcpt.excepinfo[2]; 637 if len(sRet) > 0: 638 return sRet[0:]; 639 except: 640 pass; 641 if hasattr(oXcpt, 'strerror'): 642 try: 643 sRet = oXcpt.strerror; 644 if len(sRet) > 0: 645 return sRet; 646 except: 647 pass; 648 return None; 649 650 def errGetBaseXcpt(self): 651 import pythoncom; 652 return pythoncom.com_error; 653 654 def errSetupConstants(self, oDst): 655 import winerror; 656 oDst = self.errCopyErrorConstants(oDst, winerror); 657 658 # XPCOM compatability constants. 659 oDst.NS_OK = oDst.S_OK; 660 oDst.NS_ERROR_FAILURE = oDst.E_FAIL; 661 oDst.NS_ERROR_ABORT = oDst.E_ABORT; 662 oDst.NS_ERROR_NULL_POINTER = oDst.E_POINTER; 663 oDst.NS_ERROR_NO_INTERFACE = oDst.E_NOINTERFACE; 664 oDst.NS_ERROR_INVALID_ARG = oDst.E_INVALIDARG; 665 oDst.NS_ERROR_OUT_OF_MEMORY = oDst.E_OUTOFMEMORY; 666 oDst.NS_ERROR_NOT_IMPLEMENTED = oDst.E_NOTIMPL; 667 oDst.NS_ERROR_UNEXPECTED = oDst.E_UNEXPECTED; 668 return oDst; 669 540 670 541 671 class PlatformXPCOM(PlatformBase): … … 603 733 import xpcom.components 604 734 return oIUnknown.queryInterface(getattr(xpcom.components.interfaces, sClassName)) 735 736 def errGetStatus(self, oXcpt): 737 return oXcpt.errno; 738 739 def errIsDeadInterface(self, oXcpt): 740 import winerror; 741 return self.errGetStatus(oXcpt) in [ 742 0x80004004, -2147467260, # NS_ERROR_ABORT 743 0x800706be, -2147023170, # NS_ERROR_CALL_FAILED (RPC_S_CALL_FAILED) 744 ]; 745 746 def errGetMessage(self, oXcpt): 747 if hasattr(oXcpt, 'msg'): 748 try: 749 sRet = oXcpt.msg; 750 if len(sRet) > 0: 751 return sRet; 752 except: 753 pass; 754 return None; 755 756 def errGetBaseXcpt(self): 757 import xpcom; 758 return xpcom.Exception; 759 760 def errSetupConstants(self, oDst): 761 import winerror; 762 oDst = self.errCopyErrorConstants(oDst, winerror); 763 764 # COM compatability constants. 765 oDst.E_ACCESSDENIED = -2147024891; # see VBox/com/defs.h 766 oDst.S_OK = oDst.NS_OK; 767 oDst.E_FAIL = oDst.NS_ERROR_FAILURE; 768 oDst.E_ABORT = oDst.NS_ERROR_ABORT; 769 oDst.E_POINTER = oDst.NS_ERROR_NULL_POINTER; 770 oDst.E_NOINTERFACE = oDst.NS_ERROR_NO_INTERFACE; 771 oDst.E_INVALIDARG = oDst.NS_ERROR_INVALID_ARG; 772 oDst.E_OUTOFMEMORY = oDst.NS_ERROR_OUT_OF_MEMORY; 773 oDst.E_NOTIMPL = oDst.NS_ERROR_NOT_IMPLEMENTED; 774 oDst.E_UNEXPECTED = oDst.NS_ERROR_UNEXPECTED; 775 oDst.DISP_E_EXCEPTION = -2147352567; # For COM compatability only. 776 return oDst; 605 777 606 778 … … 705 877 706 878 879 ## The current (last) exception class. 880 # This is reinitalized whenever VirtualBoxManager is called, so it will hold 881 # the reference to the error exception class for the last platform/style that 882 # was used. Most clients does talk to multiple VBox instance on different 883 # platforms at the same time, so this should be sufficent for most uses and 884 # be way simpler to use than VirtualBoxManager::oXcptClass. 885 CurXctpClass = None; 886 707 887 708 888 class VirtualBoxManager(object): … … 718 898 WEBSERVICE backend. 719 899 """ 900 901 class Statuses(object): 902 def __init__(self): 903 pass; 720 904 721 905 def __init__(self, sStyle = None, dPlatformParams = None): … … 736 920 self.type = self.platform.getType() 737 921 self.remote = self.platform.isRemote() 738 # for webservices, enums are symbolic922 ## VirtualBox API constants (for webservices, enums are symbolic). 739 923 self.constants = VirtualBoxReflectionInfo(sStyle == "WEBSERVICE") 740 924 925 ## Status constants. 926 self.statuses = self.platform.errSetupConstants(VirtualBoxManager.Statuses()); 927 ## @todo Add VBOX_E_XXX to statuses? They're already in constants... 928 ## Dictionary for errToString, built on demand. 929 self._dErrorValToName = None; 930 931 ## The exception class for the selected platform. 932 self.oXcptClass = self.platform.errGetBaseXcpt(); 933 global CurXcptClass; 934 CurXcptClass = self.oXcptClass; 935 936 # Get the virtualbox singleton. 741 937 try: 742 938 self.vbox = self.platform.getVirtualBox() … … 760 956 self.deinit() 761 957 958 def getPythonApiRevision(self): 959 """ 960 Returns a Python API revision number. 961 This will be incremented when features are added to this file. 962 """ 963 return 2; 964 762 965 763 966 # … … 868 1071 return VBoxSdkDir 869 1072 1073 1074 # 1075 # Error code utilities. 1076 # 1077 1078 ## @todo port to webservices! 1079 1080 def errGetStatus(self, oXcpt): 1081 """ 1082 Gets the status code from an exception. 1083 """ 1084 return self.platform.errGetStatus(oXcpt); 1085 1086 def errIsDeadInterface(self, oXcpt): 1087 """ 1088 Returns True if the exception indicates that the interface is dead, False if not. 1089 """ 1090 return self.platform.errIsDeadInterface(oXcpt); 1091 1092 def errIsOurXcptKind(self, oXcpt): 1093 """ 1094 Checks if the exception is one that could come from the VBox API. 1095 """ 1096 if self.oXcptClass is None: ## @todo find the exception class for web services! 1097 return False; 1098 return isinstance(oXcpt, self.oXcptClass); 1099 1100 def errIsEqual(self, oXcpt, hrStatus): 1101 """ See PlatformBase::errIsEqual(). """ 1102 return self.platform.errIsEqual(oXcpt, hrStatus); 1103 1104 def errIsNotEqual(self, oXcpt, hrStatus): 1105 """ 1106 Negated errIsEqual. 1107 """ 1108 return self.errIsEqual(oXcpt, hrStatus); 1109 1110 def errToString(self, hrStatusOrXcpt): 1111 """ 1112 Converts the specified COM status code, or the status code of the 1113 specified exception, to a C constant string. 1114 """ 1115 1116 # Deal with exceptions. 1117 if self.errIsOurXcptKind(hrStatusOrXcpt): 1118 hrStatus = self.errGetStatus(hrStatusOrXcpt); 1119 else: 1120 hrStatus = hrStatusOrXcpt; 1121 1122 # Build the dictionary on demand. 1123 if self._dErrorValToName is None: 1124 dErrorValToName = dict(); 1125 for sKey in dir(self.statuses): 1126 if sKey[0].isupper(): 1127 oValue = getattr(self.statuses, sKey); 1128 if type(oValue) is int: 1129 dErrorValToName[oValue] = sKey; 1130 self._dErrorValToName = dErrorValToName; 1131 1132 # Do the lookup, falling back on formatting the status number. 1133 try: 1134 sStr = self._dErrorValToName[int(hrStatus)]; 1135 except KeyError: 1136 hrLong = long(hrStatus); 1137 sStr = '%#x (%d)' % (hrLong, hrLong); 1138 return sStr; 1139 1140 def errGetMessage(self, oXcpt): 1141 """ 1142 Returns the best error message found in the COM-like exception. 1143 """ 1144 sRet = self.platform.errGetMessage(oXcpt); 1145 if sRet is None: 1146 sRet = self.errToString(oXcpt); 1147 return sRet; 1148
Note:
See TracChangeset
for help on using the changeset viewer.