root/trunk/include/VBox/com/SupportErrorInfo.h
| Revision 14556, 21.4 kB (checked in by vboxsync, 1 month ago) | |
|---|---|
| |
| Line | |
|---|---|
| 1 | /* $Id$ */ |
| 2 | |
| 3 | /** @file |
| 4 | * MS COM / XPCOM Abstraction Layer: |
| 5 | * SupportErrorInfo* class family declarations |
| 6 | */ |
| 7 | |
| 8 | /* |
| 9 | * Copyright (C) 2008 Sun Microsystems, Inc. |
| 10 | * |
| 11 | * This file is part of VirtualBox Open Source Edition (OSE), as |
| 12 | * available from http://www.virtualbox.org. This file is free software; |
| 13 | * you can redistribute it and/or modify it under the terms of the GNU |
| 14 | * General Public License (GPL) as published by the Free Software |
| 15 | * Foundation, in version 2 as it comes in the "COPYING" file of the |
| 16 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the |
| 17 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. |
| 18 | * |
| 19 | * The contents of this file may alternatively be used under the terms |
| 20 | * of the Common Development and Distribution License Version 1.0 |
| 21 | * (CDDL) only, as it comes in the "COPYING.CDDL" file of the |
| 22 | * VirtualBox OSE distribution, in which case the provisions of the |
| 23 | * CDDL are applicable instead of those of the GPL. |
| 24 | * |
| 25 | * You may elect to license modified versions of this file under the |
| 26 | * terms and conditions of either the GPL or the CDDL or both. |
| 27 | * |
| 28 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa |
| 29 | * Clara, CA 95054 USA or visit http://www.sun.com if you need |
| 30 | * additional information or have any questions. |
| 31 | */ |
| 32 | |
| 33 | #ifndef ___VBox_com_SupportErrorInfo_h |
| 34 | #define ___VBox_com_SupportErrorInfo_h |
| 35 | |
| 36 | #include "VBox/com/defs.h" |
| 37 | #include "VBox/com/string.h" |
| 38 | |
| 39 | #include <iprt/cdefs.h> |
| 40 | |
| 41 | #include <stdarg.h> |
| 42 | |
| 43 | #if !defined (VBOX_WITH_XPCOM) |
| 44 | interface IVirtualBoxErrorInfo; |
| 45 | #else |
| 46 | class IVirtualBoxErrorInfo; |
| 47 | #endif |
| 48 | |
| 49 | namespace com |
| 50 | { |
| 51 | |
| 52 | /** |
| 53 | * The MultiResult class is a com::FWResult enhancement that also acts as a |
| 54 | * switch to turn on multi-error mode for SupportErrorInfo::setError() and |
| 55 | * SupportErrorInfo::setWarning() calls. |
| 56 | * |
| 57 | * When an instance of this class is created, multi-error mode is turned on |
| 58 | * for the current thread and the turn-on counter is increased by one. In |
| 59 | * multi-error mode, a call to setError() or setWarning() does not |
| 60 | * overwrite the current error or warning info object possibly set on the |
| 61 | * current thread by other method calls, but instead it stores this old |
| 62 | * object in the IVirtualBoxErrorInfo::next attribute of the new error |
| 63 | * object being set. |
| 64 | * |
| 65 | * This way, error/warning objects are stacked together and form a chain of |
| 66 | * errors where the most recent error is the first one retrieved by the |
| 67 | * calling party, the preceding error is what the |
| 68 | * IVirtualBoxErrorInfo::next attribute of the first error points to, and so |
| 69 | * on, up to the first error or warning occurred which is the last in the |
| 70 | * chain. See IVirtualBoxErrorInfo documentation for more info. |
| 71 | * |
| 72 | * When the instance of the MultiResult class goes out of scope and gets |
| 73 | * destroyed, it automatically decreases the turn-on counter by one. If |
| 74 | * the counter drops to zero, multi-error mode for the current thread is |
| 75 | * turned off and the thread switches back to single-error mode where every |
| 76 | * next error or warning object overwrites the previous one. |
| 77 | * |
| 78 | * Note that the caller of a COM method uses a non-S_OK result code to |
| 79 | * decide if the method has returned an error (negative codes) or a warning |
| 80 | * (positive non-zero codes) and will query extended error info only in |
| 81 | * these two cases. However, since multi-error mode implies that the method |
| 82 | * doesn't return control return to the caller immediately after the first |
| 83 | * error or warning but continues its execution, the functionality provided |
| 84 | * by the base com::FWResult class becomes very useful because it allows to |
| 85 | * preserve the error or the warning result code even if it is later assigned |
| 86 | * a S_OK value multiple times. See com::FWResult for details. |
| 87 | * |
| 88 | * Here is the typical usage pattern: |
| 89 | * <code> |
| 90 | |
| 91 | HRESULT Bar::method() |
| 92 | { |
| 93 | // assume multi-errors are turned off here... |
| 94 | |
| 95 | if (something) |
| 96 | { |
| 97 | // Turn on multi-error mode and make sure severity is preserved |
| 98 | MultiResult rc = foo->method1(); |
| 99 | |
| 100 | // return on fatal error, but continue on warning or on success |
| 101 | CheckComRCReturnRC (rc); |
| 102 | |
| 103 | rc = foo->method2(); |
| 104 | // no matter what result, stack it and continue |
| 105 | |
| 106 | // ... |
| 107 | |
| 108 | // return the last worst result code (it will be preserved even if |
| 109 | // foo->method2() returns S_OK. |
| 110 | return rc; |
| 111 | } |
| 112 | |
| 113 | // multi-errors are turned off here again... |
| 114 | |
| 115 | return S_OK; |
| 116 | } |
| 117 | |
| 118 | * </code> |
| 119 | * |
| 120 | * @note This class is intended to be instantiated on the stack, therefore |
| 121 | * You cannot create them using new(). Although it is possible to copy |
| 122 | * instances of MultiResult or return them by value, please never do |
| 123 | * that as it is breaks the class semantics (and will assert); |
| 124 | */ |
| 125 | class MultiResult : public FWResult |
| 126 | { |
| 127 | public: |
| 128 | |
| 129 | /** |
| 130 | * @copydoc FWResult::FWResult(). |
| 131 | */ |
| 132 | MultiResult (HRESULT aRC = E_FAIL) : FWResult (aRC) { incCounter(); } |
| 133 | |
| 134 | MultiResult (const MultiResult &aThat) : FWResult (aThat) |
| 135 | { |
| 136 | /* We need this copy constructor only for GCC that wants to have |
| 137 | * it in case of expressions like |MultiResult rc = E_FAIL;|. But |
| 138 | * we assert since the optimizer should actually avoid the |
| 139 | * temporary and call the other constructor directly instead. */ |
| 140 | AssertFailed(); |
| 141 | } |
| 142 | |
| 143 | ~MultiResult() { decCounter(); } |
| 144 | |
| 145 | MultiResult &operator= (HRESULT aRC) |
| 146 | { |
| 147 | FWResult::operator= (aRC); |
| 148 | return *this; |
| 149 | } |
| 150 | |
| 151 | MultiResult &operator= (const MultiResult &aThat) |
| 152 | { |
| 153 | /* We need this copy constructor only for GCC that wants to have |
| 154 | * it in case of expressions like |MultiResult rc = E_FAIL;|. But |
| 155 | * we assert since the optimizer should actually avoid the |
| 156 | * temporary and call the other constructor directly instead */ |
| 157 | AssertFailed(); |
| 158 | return *this; |
| 159 | } |
| 160 | |
| 161 | private: |
| 162 | |
| 163 | DECLARE_CLS_NEW_DELETE_NOOP (MultiResult) |
| 164 | |
| 165 | static void incCounter(); |
| 166 | static void decCounter(); |
| 167 | |
| 168 | static RTTLS sCounter; |
| 169 | |
| 170 | friend class SupportErrorInfoBase; |
| 171 | friend class MultiResultRef; |
| 172 | }; |
| 173 | |
| 174 | /** |
| 175 | * The MultiResultRef class is equivalent to MultiResult except that it takes |
| 176 | * a reference to the existing HRESULT variable instead of maintaining its own |
| 177 | * one. |
| 178 | */ |
| 179 | class MultiResultRef |
| 180 | { |
| 181 | public: |
| 182 | |
| 183 | MultiResultRef (HRESULT &aRC) : mRC (aRC) { MultiResult::incCounter(); } |
| 184 | |
| 185 | ~MultiResultRef() { MultiResult::decCounter(); } |
| 186 | |
| 187 | MultiResultRef &operator= (HRESULT aRC) |
| 188 | { |
| 189 | /* Copied from FWResult */ |
| 190 | if ((FAILED (aRC) && !FAILED (mRC)) || |
| 191 | (mRC == S_OK && aRC != S_OK)) |
| 192 | mRC = aRC; |
| 193 | |
| 194 | return *this; |
| 195 | } |
| 196 | |
| 197 | operator HRESULT() const { return mRC; } |
| 198 | |
| 199 | HRESULT *operator&() { return &mRC; } |
| 200 | |
| 201 | private: |
| 202 | |
| 203 | DECLARE_CLS_NEW_DELETE_NOOP (MultiResultRef) |
| 204 | |
| 205 | HRESULT &mRC; |
| 206 | }; |
| 207 | |
| 208 | /** |
| 209 | * The SupportErrorInfoBase template class provides basic error info support. |
| 210 | * |
| 211 | * Basic error info support includes a group of setError() methods to set |
| 212 | * extended error information on the current thread. This support does not |
| 213 | * include all necessary implementation details (for example, implementation of |
| 214 | * the ISupportErrorInfo interface on MS COM) to make the error info support |
| 215 | * fully functional in a target component. These details are provided by the |
| 216 | * SupportErrorInfoDerived class. |
| 217 | * |
| 218 | * This way, this class is intended to be directly inherited only by |
| 219 | * intermediate component base classes that will be then inherited by final |
| 220 | * component classes through the SupportErrorInfoDerived template class. In |
| 221 | * all other cases, the SupportErrorInfoImpl class should be used as a base for |
| 222 | * final component classes instead. |
| 223 | */ |
| 224 | class SupportErrorInfoBase |
| 225 | { |
| 226 | static HRESULT setErrorInternal (HRESULT aResultCode, const GUID *aIID, |
| 227 | const char *aComponent, const char *aText, |
| 228 | bool aWarning, |
| 229 | IVirtualBoxErrorInfo *aInfo = NULL); |
| 230 | |
| 231 | protected: |
| 232 | |
| 233 | /** |
| 234 | * Returns an interface ID that is to be used in short setError() variants |
| 235 | * to specify the interface that has defined the error. Must be implemented |
| 236 | * in subclasses. |
| 237 | */ |
| 238 | virtual const GUID &mainInterfaceID() const = 0; |
| 239 | |
| 240 | /** |
| 241 | * Returns an component name (in UTF8) that is to be used in short |
| 242 | * setError() variants to specify the interface that has defined the error. |
| 243 | * Must be implemented in subclasses. |
| 244 | */ |
| 245 | virtual const char *componentName() const = 0; |
| 246 | |
| 247 | /** |
| 248 | * Sets the error information for the current thread. |
| 249 | * |
| 250 | * When the error information is set, it can be retrieved by a caller of an |
| 251 | * interface method using the respective methods that return an IErrorInfo |
| 252 | * object in MS COM (nsIException object in XPCOM) set for the current |
| 253 | * thread. This object can also be or queried for the platform-independent |
| 254 | * IVirtualBoxErrorInfo interface that provides extended error information |
| 255 | * (only for components from the VirtualBox COM library). Alternatively, the |
| 256 | * platform-independent ErrorInfo class can be used to retrieve error info |
| 257 | * in a convenient way. |
| 258 | * |
| 259 | * It is assumed that the interface method that uses this function returns |
| 260 | * an non S_OK result code to the caller (otherwise, there is no reason |
| 261 | * for the caller to check for error info after method invocation). |
| 262 | * |
| 263 | * Here is a table of correspondence between this method's arguments and |
| 264 | * IErrorInfo/nsIException/IVirtualBoxErrorInfo attributes/methods: |
| 265 | * |
| 266 | * <pre> |
| 267 | * argument IErrorInfo nsIException IVirtualBoxErrorInfo |
| 268 | * ---------------------------------------------------------------- |
| 269 | * resultCode -- result resultCode |
| 270 | * iid GetGUID -- interfaceID |
| 271 | * component GetSource -- component |
| 272 | * text GetDescription message text |
| 273 | * </pre> |
| 274 | * |
| 275 | * Note that this is a generic method. There are more convenient overloaded |
| 276 | * versions that automatically substitute some arguments taking their |
| 277 | * values from the template parameters. See #setError (HRESULT, const char |
| 278 | * *, ...) for an example. |
| 279 | * |
| 280 | * It is also possible to turn on the multi-error mode so that setting a new |
| 281 | * error information does not destroy the previous error (if any) but makes |
| 282 | * it accessible using the IVirtualBoxErrorInfo::next attribute. See |
| 283 | * MultiResult for more information. |
| 284 | * |
| 285 | * @param aResultCode Result (error) code, must not be S_OK. |
| 286 | * @param aIID IID of the interface that defines the error. |
| 287 | * @param aComponent Name of the component that sets the error (UTF8). |
| 288 | * @param aText Error message in UTF8 (must not be NULL). |
| 289 | * |
| 290 | * @return @a aResultCode argument, for convenience. If an error occurs |
| 291 | * while setting error info itself, that error is returned instead |
| 292 | * of the @a aResultCode argument. |
| 293 | */ |
| 294 | static HRESULT setError (HRESULT aResultCode, const GUID &aIID, |
| 295 | const char *aComponent, const char *aText) |
| 296 | { |
| 297 | return setErrorInternal (aResultCode, &aIID, aComponent, aText, |
| 298 | false /* aWarning */); |
| 299 | } |
| 300 | |
| 301 | /** |
| 302 | * Same as #setError() except that it makes sure that aResultCode doesn't |
| 303 | * have the error severity bit (31) set when passed down to the created |
| 304 | * IVirtualBoxErrorInfo object. |
| 305 | * |
| 306 | * The error severity bit is always cleared by this call, thereof you can |
| 307 | * use ordinary E_XXX result code constants, for convenience. However, this |
| 308 | * behavior may be non-standard on some COM platforms. |
| 309 | */ |
| 310 | static HRESULT setWarning (HRESULT aResultCode, const GUID &aIID, |
| 311 | const char *aComponent, const char *aText) |
| 312 | { |
| 313 | return setErrorInternal (aResultCode, &aIID, aComponent, aText, |
| 314 | true /* aWarning */); |
| 315 | } |
| 316 | |
| 317 | /** |
| 318 | * Same as #setError (HRESULT, const GUID &, const char *, const char *) but |
| 319 | * interprets the @a aText argument as a RTPrintf-like format string and the |
| 320 | * @a aArgs argument as an argument list for this format string. |
| 321 | */ |
| 322 | static HRESULT setErrorV (HRESULT aResultCode, const GUID &aIID, |
| 323 | const char *aComponent, const char *aText, |
| 324 | va_list aArgs) |
| 325 | { |
| 326 | return setErrorInternal (aResultCode, &aIID, aComponent, |
| 327 | Utf8StrFmtVA (aText, aArgs), |
| 328 | false /* aWarning */); |
| 329 | } |
| 330 | |
| 331 | /** |
| 332 | * Same as #setWarning (HRESULT, const GUID &, const char *, const char *) |
| 333 | * but interprets the @a aText argument as a RTPrintf-like format string and |
| 334 | * the @a aArgs argument as an argument list for this format string. |
| 335 | */ |
| 336 | static HRESULT setWarningV (HRESULT aResultCode, const GUID &aIID, |
| 337 | const char *aComponent, const char *aText, |
| 338 | va_list aArgs) |
| 339 | { |
| 340 | return setErrorInternal (aResultCode, &aIID, aComponent, |
| 341 | Utf8StrFmtVA (aText, aArgs), |
| 342 | true /* aWarning */); |
| 343 | } |
| 344 | |
| 345 | /** |
| 346 | * Same as #setError (HRESULT, const GUID &, const char *, const char *) but |
| 347 | * interprets the @a aText argument as a RTPrintf-like format string and |
| 348 | * takes a variable list of arguments for this format string. |
| 349 | */ |
| 350 | static HRESULT setError (HRESULT aResultCode, const GUID &aIID, |
| 351 | const char *aComponent, const char *aText, |
| 352 | ...); |
| 353 | |
| 354 | /** |
| 355 | * Same as #setWarning (HRESULT, const GUID &, const char *, const char *) |
| 356 | * but interprets the @a aText argument as a RTPrintf-like format string and |
| 357 | * takes a variable list of arguments for this format string. |
| 358 | */ |
| 359 | static HRESULT setWarning (HRESULT aResultCode, const GUID &aIID, |
| 360 | const char *aComponent, const char *aText, |
| 361 | ...); |
| 362 | |
| 363 | /** |
| 364 | * Sets the given error info object on the current thread. |
| 365 | * |
| 366 | * Note that In multi-error mode (see MultiResult), the existing error info |
| 367 | * object (if any) will be preserved by attaching it to the tail of the |
| 368 | * error chain of the given aInfo object. |
| 369 | * |
| 370 | * @param aInfo Error info object to set (must not be NULL). |
| 371 | */ |
| 372 | static HRESULT setErrorInfo (IVirtualBoxErrorInfo *aInfo) |
| 373 | { |
| 374 | AssertReturn (aInfo != NULL, E_FAIL); |
| 375 | return setErrorInternal (0, NULL, NULL, NULL, false, aInfo); |
| 376 | } |
| 377 | |
| 378 | /** |
| 379 | * Same as #setError (HRESULT, const GUID &, const char *, const char *, |
| 380 | * ...) but uses the return value of the mainInterfaceID() method as an @a |
| 381 | * aIID argument and the return value of the componentName() method as a @a |
| 382 | * aComponent argument. |
| 383 | * |
| 384 | * This method is the most common (and convenient) way to set error |
| 385 | * information from within a component method. The typical usage pattern is: |
| 386 | * <code> |
| 387 | * return setError (E_FAIL, "Terrible Error"); |
| 388 | * </code> |
| 389 | * or |
| 390 | * <code> |
| 391 | * HRESULT rc = setError (E_FAIL, "Terrible Error"); |
| 392 | * ... |
| 393 | * return rc; |
| 394 | * </code> |
| 395 | */ |
| 396 | HRESULT setError (HRESULT aResultCode, const char *aText, ...); |
| 397 | |
| 398 | /** |
| 399 | * Same as #setWarning (HRESULT, const GUID &, const char *, const char *, |
| 400 | * ...) but uses the return value of the mainInterfaceID() method as an @a |
| 401 | * aIID argument and the return value of the componentName() method as a @a |
| 402 | * aComponent argument. |
| 403 | * |
| 404 | * This method is the most common (and convenient) way to set warning |
| 405 | * information from within a component method. The typical usage pattern is: |
| 406 | * <code> |
| 407 | * return setWarning (E_FAIL, "Dangerous warning"); |
| 408 | * </code> |
| 409 | * or |
| 410 | * <code> |
| 411 | * HRESULT rc = setWarning (E_FAIL, "Dangerous warning"); |
| 412 | * ... |
| 413 | * return rc; |
| 414 | * </code> |
| 415 | */ |
| 416 | HRESULT setWarning (HRESULT aResultCode, const char *aText, ...); |
| 417 | |
| 418 | /** |
| 419 | * Same as #setError (HRESULT, const char *, ...) but takes a va_list |
| 420 | * argument instead of a variable argument list. |
| 421 | */ |
| 422 | HRESULT setErrorV (HRESULT aResultCode, const char *aText, va_list aArgs) |
| 423 | { |
| 424 | return setError (aResultCode, mainInterfaceID(), componentName(), |
| 425 | aText, aArgs); |
| 426 | } |
| 427 | |
| 428 | /** |
| 429 | * Same as #setWarning (HRESULT, const char *, ...) but takes a va_list |
| 430 | * argument instead of a variable argument list. |
| 431 | */ |
| 432 | HRESULT setWarningV (HRESULT aResultCode, const char *aText, va_list aArgs) |
| 433 | { |
| 434 | return setWarning (aResultCode, mainInterfaceID(), componentName(), |
| 435 | aText, aArgs); |
| 436 | } |
| 437 | |
| 438 | /** |
| 439 | * Same as #setError (HRESULT, const char *, ...) but allows to specify the |
| 440 | * interface ID manually. |
| 441 | */ |
| 442 | HRESULT setError (HRESULT aResultCode, const GUID &aIID, |
| 443 | const char *aText, ...); |
| 444 | |
| 445 | /** |
| 446 | * Same as #setWarning (HRESULT, const char *, ...) but allows to specify |
| 447 | * the interface ID manually. |
| 448 | */ |
| 449 | HRESULT setWarning (HRESULT aResultCode, const GUID &aIID, |
| 450 | const char *aText, ...); |
| 451 | }; |
| 452 | |
| 453 | //////////////////////////////////////////////////////////////////////////////// |
| 454 | |
| 455 | /** |
| 456 | * The SupportErrorInfoDerived template class implements the remaining parts |
| 457 | * of error info support in addition to SupportErrorInfoBase. |
| 458 | * |
| 459 | * These parts include the ISupportErrorInfo implementation on the MS COM |
| 460 | * platform and implementations of mandatory SupportErrorInfoBase virtual |
| 461 | * methods. |
| 462 | * |
| 463 | * On MS COM, the @a C template argument must declare a COM interface map using |
| 464 | * BEGIN_COM_MAP / END_COM_MAP macros and this map must contain a |
| 465 | * COM_INTERFACE_ENTRY(ISupportErrorInfo) definition. All interface entries that |
| 466 | * follow it will be considered to support IErrorInfo, i.e. the |
| 467 | * InterfaceSupportsErrorInfo() implementation will return S_OK for the |
| 468 | * corresponding IIDs. |
| 469 | * |
| 470 | * On all platforms, the @a C template argument must be a subclass of |
| 471 | * SupportErrorInfoBase and also define the following method: <tt>public static |
| 472 | * const char *ComponentName()</tt> that will be used as a value returned by the |
| 473 | * SupportErrorInfoBase::componentName() implementation. |
| 474 | * |
| 475 | * If SupportErrorInfoBase is used as a base for an intermediate component base |
| 476 | * class FooBase then the final component FooFinal that inherits FooBase should |
| 477 | * use this template class as follows: |
| 478 | * <code> |
| 479 | * class FooFinal : public SupportErrorInfoDerived <FooBase, FooFinal, IFoo> |
| 480 | * { |
| 481 | * ... |
| 482 | * }; |
| 483 | * </code> |
| 484 | * |
| 485 | * Note that if you don not use intermediate component base classes, you should |
| 486 | * use the SupportErrorInfoImpl class as a base for your component instead. |
| 487 | * |
| 488 | * @param B Intermediate component base derived from SupportErrorInfoBase. |
| 489 | * @param C Component class that implements one or more COM interfaces. |
| 490 | * @param I Default interface for the component (for short #setError() |
| 491 | * versions). |
| 492 | */ |
| 493 | template <class B, class C, class I> |
| 494 | class ATL_NO_VTABLE SupportErrorInfoDerived : public B |
| 495 | #if !defined (VBOX_WITH_XPCOM) |
| 496 | , public ISupportErrorInfo |
| 497 | #endif |
| 498 | { |
| 499 | public: |
| 500 | |
| 501 | #if !defined (VBOX_WITH_XPCOM) |
| 502 | STDMETHOD(InterfaceSupportsErrorInfo) (REFIID aIID) |
| 503 | { |
| 504 | const _ATL_INTMAP_ENTRY* pEntries = C::_GetEntries(); |
| 505 | Assert (pEntries); |
| 506 | if (!pEntries) |
| 507 | return S_FALSE; |
| 508 | |
| 509 | BOOL bSupports = FALSE; |
| 510 | BOOL bISupportErrorInfoFound = FALSE; |
| 511 | |
| 512 | while (pEntries->pFunc != NULL && !bSupports) |
| 513 | { |
| 514 | if (!bISupportErrorInfoFound) |
| 515 | { |
| 516 | /* skip the COM map entries until ISupportErrorInfo is found */ |
| 517 | bISupportErrorInfoFound = |
| 518 | InlineIsEqualGUID (*(pEntries->piid), IID_ISupportErrorInfo); |
| 519 | } |
| 520 | else |
| 521 | { |
| 522 | /* look for the requested interface in the rest of the com map */ |
| 523 | bSupports = InlineIsEqualGUID (*(pEntries->piid), aIID); |
| 524 | } |
| 525 | pEntries++; |
| 526 | } |
| 527 | |
| 528 | Assert (bISupportErrorInfoFound); |
| 529 | |
| 530 | return bSupports ? S_OK : S_FALSE; |
| 531 | } |
| 532 | #endif /* !defined (VBOX_WITH_XPCOM) */ |
| 533 | |
| 534 | protected: |
| 535 | |
| 536 | virtual const GUID &mainInterfaceID() const { return COM_IIDOF (I); } |
| 537 | |
| 538 | virtual const char *componentName() const { return C::ComponentName(); } |
| 539 | }; |
| 540 | |
| 541 | //////////////////////////////////////////////////////////////////////////////// |
| 542 | |
| 543 | /** |
| 544 | * The SupportErrorInfoImpl template class provides complete error info support |
| 545 | * for COM component classes. |
| 546 | * |
| 547 | * Complete error info support includes what both SupportErrorInfoBase and |
| 548 | * SupportErrorInfoDerived provide, e.g. a variety of setError() methods to |
| 549 | * set extended error information from within a component's method |
| 550 | * implementation and all necessary additional interface implementations (see |
| 551 | * descriptions of these classes for details). |
| 552 | * |
| 553 | * To add error info support to a Foo component that implements a IFoo |
| 554 | * interface, use the following pattern: |
| 555 | * <code> |
| 556 | * class Foo : public SupportErrorInfoImpl <Foo, IFoo> |
| 557 | * { |
| 558 | * public: |
| 559 | * |
| 560 | * ... |
| 561 | * |
| 562 | * static const char *ComponentName() const { return "Foo"; } |
| 563 | * }; |
| 564 | * </code> |
| 565 | * |
| 566 | * Note that your component class (the @a C template argument) must provide the |
| 567 | * ComponentName() implementation as shown above. |
| 568 | * |
| 569 | * @param C Component class that implements one or more COM interfaces. |
| 570 | * @param I Default interface for the component (for short #setError() |
| 571 | * versions). |
| 572 | */ |
| 573 | template <class C, class I> |
| 574 | class ATL_NO_VTABLE SupportErrorInfoImpl |
| 575 | : public SupportErrorInfoDerived <SupportErrorInfoBase, C, I> |
| 576 | { |
| 577 | }; |
| 578 | |
| 579 | } /* namespace com */ |
| 580 | |
| 581 | #endif /* ___VBox_com_SupportErrorInfo_h */ |
| 582 |
Note: See TracBrowser for help on using the browser.

