The underlying storage for a CComBSTR is the public member CComBSTR::m_str, which is a BSTR. Now, a BSTR is typdef'ed as OLECHAR *BSTR, and an OLECHAR* is typdef'ed as a WCHAR. A WCHAR is a wchar_t, so it follows then that all a CComBSTR is is a wrapper around a wchar_t*.

Internally, the constructor has the code

m_str = ::SysAllocString(pSrc);

where pSrc is the string you passed in. The destructor, I would assume, calls SysFreeString, passing m_str. (I cannot prove this since I cannot step into the destructor for some reason).

Anyway, that being said, you can see that you can use standard wide string handling API functions to manipulate the member m_str, or, as I did, std::wstring, which is a lot easier. The only thing you need to watch out for is that you take care of the memory occupied by m_str, if, for example, you increase the length of it. You could write a wrapper function to do a replace operation, something like the code below.