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