/* * PROJECT: ReactOS crt library * LICENSE: GPLv2+ - See COPYING in the top level directory * PURPOSE: Compiler support for COM * PROGRAMMER: Thomas Faber (thomas.faber@reactos.org) */ #include #define WIN32_NO_STATUS #define _INC_WINDOWS #include #include #include /* comdef.h */ typedef void WINAPI COM_ERROR_HANDLER(HRESULT, IErrorInfo *); static COM_ERROR_HANDLER *com_error_handler; void WINAPI _com_raise_error(HRESULT hr, IErrorInfo *perrinfo) { throw _com_error(hr, perrinfo); } void WINAPI _set_com_error_handler(COM_ERROR_HANDLER *phandler) { com_error_handler = phandler; } void WINAPI _com_issue_error(HRESULT hr) { com_error_handler(hr, NULL); } void WINAPI _com_issue_errorex(HRESULT hr, IUnknown *punk, REFIID riid) { void *pv; IErrorInfo *perrinfo = NULL; if (SUCCEEDED(punk->QueryInterface(riid, &pv))) { ISupportErrorInfo *pserrinfo = static_cast(pv); if (pserrinfo->InterfaceSupportsErrorInfo(riid) == S_OK) (void)GetErrorInfo(0, &perrinfo); pserrinfo->Release(); } com_error_handler(hr, perrinfo); } /* comutil.h */ _variant_t vtMissing(DISP_E_PARAMNOTFOUND, VT_ERROR); namespace _com_util { BSTR WINAPI ConvertStringToBSTR(const char *pSrc) { DWORD cwch; BSTR wsOut(NULL); if (!pSrc) return NULL; /* Compute the needed size with the NULL terminator */ cwch = ::MultiByteToWideChar(CP_ACP, 0, pSrc, -1, NULL, 0); if (cwch == 0) return NULL; /* Allocate the BSTR (without the NULL terminator) */ wsOut = ::SysAllocStringLen(NULL, cwch - 1); if (!wsOut) { ::_com_issue_error(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY)); return NULL; } /* Convert the string */ if (::MultiByteToWideChar(CP_ACP, 0, pSrc, -1, wsOut, cwch) == 0) { /* We failed, clean everything up */ cwch = ::GetLastError(); ::SysFreeString(wsOut); wsOut = NULL; ::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch); } return wsOut; } char* WINAPI ConvertBSTRToString(BSTR pSrc) { DWORD cb, cwch; char *szOut = NULL; if (!pSrc) return NULL; /* Retrieve the size of the BSTR with the NULL terminator */ cwch = ::SysStringLen(pSrc) + 1; /* Compute the needed size with the NULL terminator */ cb = ::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch, NULL, 0, NULL, NULL); if (cb == 0) { cwch = ::GetLastError(); ::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch); return NULL; } /* Allocate the string */ szOut = (char*)::operator new(cb * sizeof(char)); if (!szOut) { ::_com_issue_error(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY)); return NULL; } /* Convert the string and NULL-terminate */ szOut[cb - 1] = '\0'; if (::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch, szOut, cb, NULL, NULL) == 0) { /* We failed, clean everything up */ cwch = ::GetLastError(); ::operator delete(szOut); szOut = NULL; ::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch); } return szOut; } }