1 /* 2 * PROJECT: ReactOS crt library 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Compiler support for COM 5 * PROGRAMMER: Thomas Faber (thomas.faber@reactos.org) 6 */ 7 8 #include <stdarg.h> 9 10 #define WIN32_NO_STATUS 11 #define _INC_WINDOWS 12 13 #include <windef.h> 14 #include <winbase.h> 15 #include <comdef.h> 16 17 /* comdef.h */ 18 typedef void WINAPI COM_ERROR_HANDLER(HRESULT, IErrorInfo *); 19 static COM_ERROR_HANDLER *com_error_handler; 20 21 void WINAPI _com_raise_error(HRESULT hr, IErrorInfo *perrinfo) 22 { 23 throw _com_error(hr, perrinfo); 24 } 25 26 void WINAPI _set_com_error_handler(COM_ERROR_HANDLER *phandler) 27 { 28 com_error_handler = phandler; 29 } 30 31 void WINAPI _com_issue_error(HRESULT hr) 32 { 33 com_error_handler(hr, NULL); 34 } 35 36 void WINAPI _com_issue_errorex(HRESULT hr, IUnknown *punk, REFIID riid) 37 { 38 void *pv; 39 IErrorInfo *perrinfo = NULL; 40 41 if (SUCCEEDED(punk->QueryInterface(riid, &pv))) 42 { 43 ISupportErrorInfo *pserrinfo = static_cast<ISupportErrorInfo *>(pv); 44 if (pserrinfo->InterfaceSupportsErrorInfo(riid) == S_OK) 45 (void)GetErrorInfo(0, &perrinfo); 46 pserrinfo->Release(); 47 } 48 49 com_error_handler(hr, perrinfo); 50 } 51 52 /* comutil.h */ 53 _variant_t vtMissing(DISP_E_PARAMNOTFOUND, VT_ERROR); 54 55 namespace _com_util 56 { 57 58 BSTR WINAPI ConvertStringToBSTR(const char *pSrc) 59 { 60 DWORD cwch; 61 BSTR wsOut(NULL); 62 63 if (!pSrc) return NULL; 64 65 /* Compute the needed size with the NULL terminator */ 66 cwch = ::MultiByteToWideChar(CP_ACP, 0, pSrc, -1, NULL, 0); 67 if (cwch == 0) return NULL; 68 69 /* Allocate the BSTR (without the NULL terminator) */ 70 wsOut = ::SysAllocStringLen(NULL, cwch - 1); 71 if (!wsOut) 72 { 73 ::_com_issue_error(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY)); 74 return NULL; 75 } 76 77 /* Convert the string */ 78 if (::MultiByteToWideChar(CP_ACP, 0, pSrc, -1, wsOut, cwch) == 0) 79 { 80 /* We failed, clean everything up */ 81 cwch = ::GetLastError(); 82 83 ::SysFreeString(wsOut); 84 wsOut = NULL; 85 86 ::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch); 87 } 88 89 return wsOut; 90 } 91 92 char* WINAPI ConvertBSTRToString(BSTR pSrc) 93 { 94 DWORD cb, cwch; 95 char *szOut = NULL; 96 97 if (!pSrc) return NULL; 98 99 /* Retrieve the size of the BSTR with the NULL terminator */ 100 cwch = ::SysStringLen(pSrc) + 1; 101 102 /* Compute the needed size with the NULL terminator */ 103 cb = ::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch, NULL, 0, NULL, NULL); 104 if (cb == 0) 105 { 106 cwch = ::GetLastError(); 107 ::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch); 108 return NULL; 109 } 110 111 /* Allocate the string */ 112 szOut = (char*)::operator new(cb * sizeof(char)); 113 if (!szOut) 114 { 115 ::_com_issue_error(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY)); 116 return NULL; 117 } 118 119 /* Convert the string and NULL-terminate */ 120 szOut[cb - 1] = '\0'; 121 if (::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch, szOut, cb, NULL, NULL) == 0) 122 { 123 /* We failed, clean everything up */ 124 cwch = ::GetLastError(); 125 126 ::operator delete(szOut); 127 szOut = NULL; 128 129 ::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch); 130 } 131 132 return szOut; 133 } 134 135 } 136