xref: /reactos/sdk/lib/comsupp/comsupp.cpp (revision be336316)
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 */
19 typedef void WINAPI COM_ERROR_HANDLER(HRESULT, IErrorInfo *);
20 static COM_ERROR_HANDLER *com_error_handler;
21 
_com_raise_error(HRESULT hr,IErrorInfo * perrinfo)22 void WINAPI _com_raise_error(HRESULT hr, IErrorInfo *perrinfo)
23 {
24     throw _com_error(hr, perrinfo);
25 }
26 
_set_com_error_handler(COM_ERROR_HANDLER * phandler)27 void WINAPI _set_com_error_handler(COM_ERROR_HANDLER *phandler)
28 {
29     com_error_handler = phandler;
30 }
31 
_com_issue_error(HRESULT hr)32 void WINAPI _com_issue_error(HRESULT hr)
33 {
34     com_error_handler(hr, NULL);
35 }
36 
_com_issue_errorex(HRESULT hr,IUnknown * punk,REFIID riid)37 void 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 
56 namespace _com_util
57 {
58 
ConvertStringToBSTR(const char * pSrc)59 BSTR 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 
ConvertBSTRToString(BSTR pSrc)93 char* 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 }
137