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