1b97a21d40550bdd8a67b293580fc87c5ea4cda5
[reactos.git] / reactos / lib / sdk / comsupp / comsupp.cpp
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 /* CP_UTF8 */, 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 /* CP_UTF8 */, 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 /* CP_UTF8 */, 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 = new char[cb];
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 /* CP_UTF8 */, 0, pSrc, cwch, szOut, cb, NULL, NULL) == 0)
122 {
123 /* We failed, clean everything up */
124 cwch = ::GetLastError();
125
126 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 }