/Plugins/SDK/COMError.cpp

https://github.com/Templier/desktopx · C++ · 138 lines · 69 code · 15 blank · 54 comment · 19 complexity · 9ae04a82f6b0d8370242db034f4a56e1 MD5 · raw file

  1. ///////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // CCOMError Class - Error Dispatch for COM components
  4. //
  5. // Copyright (c) 2008-2011, Julien Templier
  6. // All rights reserved.
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////////////////////
  9. //
  10. // Redistribution and use in source and binary forms, with or without modification, are
  11. // permitted provided that the following conditions are met:
  12. // 1. Redistributions of source code must retain the above copyright notice, this list of
  13. // conditions and the following disclaimer.
  14. // 2. Redistributions in binary form must reproduce the above copyright notice, this list
  15. // of conditions and the following disclaimer in the documentation and/or other materials
  16. // provided with the distribution.
  17. // 3. The name of the author may not be used to endorse or promote products derived from this
  18. // software without specific prior written permission.
  19. //
  20. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  21. // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  22. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24. // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  25. // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  26. // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  27. // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. // POSSIBILITY OF SUCH DAMAGE.
  29. //
  30. ///////////////////////////////////////////////////////////////////////////////////////////////
  31. #include "COMError.h"
  32. #include <crtdbg.h>
  33. #include <atlbase.h>
  34. // Throws an exception corresponding to the given Win32 Error code.
  35. // GUID is the CLSID of the component throwing error.
  36. HRESULT CCOMError::DispatchWin32Error(DWORD error, REFCLSID clsid, LPCTSTR source,
  37. DWORD helpContext, LPCTSTR helpFileName)
  38. {
  39. // Dispatch the requested error message
  40. return DispatchError(HRESULT_FROM_WIN32(error), clsid, source, NULL, helpContext, helpFileName);
  41. }
  42. // Throws the given error code and the message corresponding to the code. If the code is
  43. // a standard code and no message is provided, then the message is extracted from the system.
  44. HRESULT CCOMError::DispatchError(HRESULT hError, REFCLSID clsid, LPCTSTR source, LPCTSTR description,
  45. DWORD helpContext, LPCTSTR helpFileName)
  46. {
  47. // This function uses ATL conversion macros
  48. // (Hence we must use this MACRO provided by ATL)
  49. USES_CONVERSION;
  50. // Convert the description to OLE string
  51. LPOLESTR wszError = NULL;
  52. if(description != NULL)
  53. {
  54. // Convert to wide char
  55. wszError = T2OLE(description);
  56. }
  57. else
  58. {
  59. // If the code is a Win32 error code
  60. if(HRESULT_FACILITY(hError) == FACILITY_WIN32)
  61. {
  62. // Get the error from the system
  63. LPTSTR szError = NULL;
  64. if(!::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  65. NULL,
  66. HRESULT_CODE(hError),
  67. MAKELANGID(LANG_USER_DEFAULT, SUBLANG_DEFAULT),
  68. (LPTSTR)&szError,
  69. 0,
  70. NULL))
  71. return HRESULT_FROM_WIN32(GetLastError());
  72. // Convert the Error multibyte string to OLE string
  73. if(szError != NULL)
  74. {
  75. // Convert to wide char
  76. wszError = T2OLE(szError);
  77. // Free the multibyte string
  78. LocalFree(szError);
  79. }
  80. }
  81. }
  82. // Convert the source string to OLE string
  83. LPOLESTR wszSource = NULL;
  84. if(source != NULL)
  85. wszSource = T2OLE(source);
  86. // Convert the help filename to OLE string
  87. LPOLESTR wszHelpFile = NULL;
  88. if(helpFileName != NULL)
  89. wszHelpFile = T2OLE(helpFileName);
  90. // Get the ICreateErrorInfo Interface
  91. ICreateErrorInfo *pCreateErrorInfo = NULL;
  92. HRESULT hSuccess = CreateErrorInfo(&pCreateErrorInfo);
  93. ATLASSERT(SUCCEEDED(hSuccess));
  94. // Fill the error information into it
  95. pCreateErrorInfo->SetGUID(clsid);
  96. if(wszError != NULL)
  97. pCreateErrorInfo->SetDescription(wszError);
  98. if(wszSource != NULL)
  99. pCreateErrorInfo->SetSource(wszSource);
  100. if(wszHelpFile != NULL)
  101. pCreateErrorInfo->SetHelpFile(wszHelpFile);
  102. pCreateErrorInfo->SetHelpContext(helpContext);
  103. // Get the IErrorInfo interface
  104. IErrorInfo *pErrorInfo = NULL;
  105. hSuccess = pCreateErrorInfo->QueryInterface(IID_IErrorInfo, (LPVOID *)&pErrorInfo);
  106. if(FAILED(hSuccess))
  107. {
  108. pCreateErrorInfo->Release();
  109. return hSuccess;
  110. }
  111. // Set this error information in the current thread
  112. hSuccess = SetErrorInfo(0, pErrorInfo);
  113. // Finally release the interfaces
  114. pCreateErrorInfo->Release();
  115. pErrorInfo->Release();
  116. // Failed to set the error info!
  117. if(FAILED(hSuccess))
  118. return hSuccess;
  119. // And, Return the error code that was asked
  120. // to be dispatched
  121. HRESULT result = MAKE_HRESULT(1, FACILITY_ITF, hError);
  122. return result;
  123. }