[COMSUPP]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 18 Oct 2015 01:20:20 +0000 (01:20 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 18 Oct 2015 01:20:20 +0000 (01:20 +0000)
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-and-com-util i.e. without reproducing the bugs of MS version.

svn path=/trunk/; revision=69581

reactos/lib/sdk/comsupp/comsupp.cpp

index fdf8658..239e7f5 100644 (file)
@@ -51,3 +51,86 @@ void WINAPI _com_issue_errorex(HRESULT hr, IUnknown *punk, REFIID riid)
 
 /* 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;
+}
+
+}