Author: hbelusca Date: Sun Oct 18 01:20:20 2015 New Revision: 69581
URL: http://svn.reactos.org/svn/reactos?rev=69581&view=rev Log: [COMSUPP] Implement _com_util::ConvertStringToBSTR and _com_util::ConvertBSTRToString (needed by _bstr_t and _variant_t classes), inspired by the remarks made in http://www.codeproject.com/Articles/1969/BUG-in-com-util-ConvertStringToBSTR... i.e. without reproducing the bugs of MS version.
Modified: trunk/reactos/lib/sdk/comsupp/comsupp.cpp
Modified: trunk/reactos/lib/sdk/comsupp/comsupp.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/comsupp/comsupp.cpp... ============================================================================== --- trunk/reactos/lib/sdk/comsupp/comsupp.cpp [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/comsupp/comsupp.cpp [iso-8859-1] Sun Oct 18 01:20:20 2015 @@ -51,3 +51,86 @@
/* 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 without the NULL terminator */ + cwch = ::MultiByteToWideChar(CP_ACP /* CP_UTF8 */, 0, pSrc, -1, NULL, 0); + if (cwch == 0) return NULL; + cwch--; + + /* Allocate the BSTR */ + wsOut = ::SysAllocStringLen(NULL, cwch); + if (!wsOut) + { + ::_com_issue_error(HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY)); + return NULL; + } + + /* Convert the string */ + if (::MultiByteToWideChar(CP_ACP /* CP_UTF8 */, 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 without the NULL terminator */ + cwch = ::SysStringLen(pSrc); + + /* Compute the needed size with the NULL terminator */ + cb = ::WideCharToMultiByte(CP_ACP /* CP_UTF8 */, 0, pSrc, cwch + 1, 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 = new char[cb]; + 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 /* CP_UTF8 */, 0, pSrc, cwch + 1, szOut, cb, NULL, NULL) == 0) + { + /* We failed, clean everything up */ + cwch = ::GetLastError(); + + delete[] szOut; + szOut = NULL; + + ::_com_issue_error(!IS_ERROR(cwch) ? HRESULT_FROM_WIN32(cwch) : cwch); + } + + return szOut; +} + +}